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

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2386
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
/* e1000_hw.c
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
 * Shared functions for accessing and configuring the MAC
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include "e1000.h"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
static s32 e1000_check_downshift(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static s32 e1000_check_polarity(struct e1000_hw *hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
				e1000_rev_polarity *polarity);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
static void e1000_clear_vfta(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
					      bool link_up);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
static s32 e1000_detect_gig_phy(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
				  u16 *max_length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
static s32 e1000_id_led_init(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
static void e1000_init_rx_addrs(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
				  struct e1000_phy_info *phy_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
				  struct e1000_phy_info *phy_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
static s32 e1000_wait_autoneg(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
static s32 e1000_set_phy_type(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
static void e1000_phy_init_script(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
static s32 e1000_setup_copper_link(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data, u16 count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
				  u16 words, u16 *data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
					u16 words, u16 *data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data, u16 count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
				  u16 phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
				 u16 *phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
static s32 e1000_acquire_eeprom(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
static void e1000_release_eeprom(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
static void e1000_standby_eeprom(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
static s32 e1000_set_vco_speed(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
static s32 e1000_set_phy_mode(struct e1000_hw *hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
				u16 *data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
				 u16 *data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
/* IGP cable length table */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
static const
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
u16 e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
	5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
	40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
	60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
	90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	    100,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	    110, 110,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	    120, 120
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
};
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static DEFINE_SPINLOCK(e1000_eeprom_lock);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
 * e1000_set_phy_type - Set the phy type member in the hw struct.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static s32 e1000_set_phy_type(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	e_dbg("e1000_set_phy_type");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	if (hw->mac_type == e1000_undefined)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
		return -E1000_ERR_PHY_TYPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	switch (hw->phy_id) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	case M88E1000_E_PHY_ID:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	case M88E1000_I_PHY_ID:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	case M88E1011_I_PHY_ID:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	case M88E1111_I_PHY_ID:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	case M88E1118_E_PHY_ID:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
		hw->phy_type = e1000_phy_m88;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	case IGP01E1000_I_PHY_ID:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
		if (hw->mac_type == e1000_82541 ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
		    hw->mac_type == e1000_82541_rev_2 ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
		    hw->mac_type == e1000_82547 ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
		    hw->mac_type == e1000_82547_rev_2)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
			hw->phy_type = e1000_phy_igp;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
	case RTL8211B_PHY_ID:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
		hw->phy_type = e1000_phy_8211;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
	case RTL8201N_PHY_ID:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
		hw->phy_type = e1000_phy_8201;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
		/* Should never have loaded on this device */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
		hw->phy_type = e1000_phy_undefined;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
		return -E1000_ERR_PHY_TYPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
 * e1000_phy_init_script - IGP phy init script - initializes the GbE PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_phy_init_script(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
	u32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
	u16 phy_saved_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
	e_dbg("e1000_phy_init_script");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
	if (hw->phy_init_script) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
		msleep(20);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
		/* Save off the current value of register 0x2F5B to be restored at
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
		 * the end of this routine. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
		ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
		/* Disabled the PHY transmitter */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
		msleep(20);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
		e1000_write_phy_reg(hw, 0x0000, 0x0140);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
		msleep(5);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
		switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
		case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
		case e1000_82547:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
			e1000_write_phy_reg(hw, 0x1F95, 0x0001);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
			e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
			e1000_write_phy_reg(hw, 0x1F79, 0x0018);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
			e1000_write_phy_reg(hw, 0x1F30, 0x1600);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
			e1000_write_phy_reg(hw, 0x1F31, 0x0014);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
			e1000_write_phy_reg(hw, 0x1F32, 0x161C);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
			e1000_write_phy_reg(hw, 0x1F94, 0x0003);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
			e1000_write_phy_reg(hw, 0x1F96, 0x003F);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
			e1000_write_phy_reg(hw, 0x2010, 0x0008);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
		case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
		case e1000_82547_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
			e1000_write_phy_reg(hw, 0x1F73, 0x0099);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
		default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		e1000_write_phy_reg(hw, 0x0000, 0x3300);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
		msleep(20);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
		/* Now enable the transmitter */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
		e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
		if (hw->mac_type == e1000_82547) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
			u16 fused, fine, coarse;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
			/* Move to analog registers page */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
			e1000_read_phy_reg(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
					   IGP01E1000_ANALOG_SPARE_FUSE_STATUS,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
					   &fused);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
			if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
				e1000_read_phy_reg(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
						   IGP01E1000_ANALOG_FUSE_STATUS,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
						   &fused);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
				fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
				coarse =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
				    fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
				if (coarse >
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
				    IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
					coarse -=
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
					    IGP01E1000_ANALOG_FUSE_COARSE_10;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
					fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
				} else if (coarse ==
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
					   IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
					fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
				fused =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
				    (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
				    (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
				    (coarse &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
				     IGP01E1000_ANALOG_FUSE_COARSE_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
				e1000_write_phy_reg(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
						    IGP01E1000_ANALOG_FUSE_CONTROL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
						    fused);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
				e1000_write_phy_reg(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
						    IGP01E1000_ANALOG_FUSE_BYPASS,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
						    IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
 * e1000_set_mac_type - Set the mac type member in the hw struct.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
s32 e1000_set_mac_type(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	e_dbg("e1000_set_mac_type");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	switch (hw->device_id) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	case E1000_DEV_ID_82542:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
		switch (hw->revision_id) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
		case E1000_82542_2_0_REV_ID:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
			hw->mac_type = e1000_82542_rev2_0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
		case E1000_82542_2_1_REV_ID:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
			hw->mac_type = e1000_82542_rev2_1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
		default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
			/* Invalid 82542 revision ID */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
			return -E1000_ERR_MAC_TYPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	case E1000_DEV_ID_82543GC_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	case E1000_DEV_ID_82543GC_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
		hw->mac_type = e1000_82543;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	case E1000_DEV_ID_82544EI_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	case E1000_DEV_ID_82544EI_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	case E1000_DEV_ID_82544GC_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	case E1000_DEV_ID_82544GC_LOM:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		hw->mac_type = e1000_82544;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	case E1000_DEV_ID_82540EM:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	case E1000_DEV_ID_82540EM_LOM:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	case E1000_DEV_ID_82540EP:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	case E1000_DEV_ID_82540EP_LOM:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	case E1000_DEV_ID_82540EP_LP:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
		hw->mac_type = e1000_82540;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	case E1000_DEV_ID_82545EM_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	case E1000_DEV_ID_82545EM_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		hw->mac_type = e1000_82545;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	case E1000_DEV_ID_82545GM_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	case E1000_DEV_ID_82545GM_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	case E1000_DEV_ID_82545GM_SERDES:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
		hw->mac_type = e1000_82545_rev_3;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	case E1000_DEV_ID_82546EB_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	case E1000_DEV_ID_82546EB_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
		hw->mac_type = e1000_82546;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	case E1000_DEV_ID_82546GB_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	case E1000_DEV_ID_82546GB_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	case E1000_DEV_ID_82546GB_SERDES:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	case E1000_DEV_ID_82546GB_PCIE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	case E1000_DEV_ID_82546GB_QUAD_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
		hw->mac_type = e1000_82546_rev_3;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	case E1000_DEV_ID_82541EI:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	case E1000_DEV_ID_82541EI_MOBILE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	case E1000_DEV_ID_82541ER_LOM:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		hw->mac_type = e1000_82541;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	case E1000_DEV_ID_82541ER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	case E1000_DEV_ID_82541GI:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	case E1000_DEV_ID_82541GI_LF:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	case E1000_DEV_ID_82541GI_MOBILE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
		hw->mac_type = e1000_82541_rev_2;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	case E1000_DEV_ID_82547EI:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	case E1000_DEV_ID_82547EI_MOBILE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
		hw->mac_type = e1000_82547;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	case E1000_DEV_ID_82547GI:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		hw->mac_type = e1000_82547_rev_2;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	case E1000_DEV_ID_INTEL_CE4100_GBE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
		hw->mac_type = e1000_ce4100;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		/* Should never have loaded on this device */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		return -E1000_ERR_MAC_TYPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	case e1000_82547:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	case e1000_82547_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		hw->asf_firmware_present = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	/* The 82543 chip does not count tx_carrier_errors properly in
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
	 * FD mode
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	if (hw->mac_type == e1000_82543)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		hw->bad_tx_carr_stats_fd = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
	if (hw->mac_type > e1000_82544)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
		hw->has_smbus = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
 * e1000_set_media_type - Set media type and TBI compatibility.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
void e1000_set_media_type(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	u32 status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	e_dbg("e1000_set_media_type");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	if (hw->mac_type != e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
		/* tbi_compatibility is only valid on 82543 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		hw->tbi_compatibility_en = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	switch (hw->device_id) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
	case E1000_DEV_ID_82545GM_SERDES:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	case E1000_DEV_ID_82546GB_SERDES:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		hw->media_type = e1000_media_type_internal_serdes;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
		switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
		case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
		case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
			hw->media_type = e1000_media_type_fiber;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
		case e1000_ce4100:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
			hw->media_type = e1000_media_type_copper;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
		default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
			status = er32(STATUS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
			if (status & E1000_STATUS_TBIMODE) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
				hw->media_type = e1000_media_type_fiber;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
				/* tbi_compatibility not valid on fiber */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
				hw->tbi_compatibility_en = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
				hw->media_type = e1000_media_type_copper;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
 * e1000_reset_hw: reset the hardware completely
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
 * Reset the transmit and receive units; mask and clear all interrupts.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
s32 e1000_reset_hw(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	u32 ctrl_ext;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	u32 icr;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	u32 manc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	u32 led_ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	e_dbg("e1000_reset_hw");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	/* For 82542 (rev 2.0), disable MWI before issuing a device reset */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	if (hw->mac_type == e1000_82542_rev2_0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
		e_dbg("Disabling MWI on 82542 rev 2.0\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
		e1000_pci_clear_mwi(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	/* Clear interrupt mask to stop board from generating interrupts */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	e_dbg("Masking off all interrupts\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	ew32(IMC, 0xffffffff);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	/* Disable the Transmit and Receive units.  Then delay to allow
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	 * any pending transactions to complete before we hit the MAC with
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	 * the global reset.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	ew32(RCTL, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	ew32(TCTL, E1000_TCTL_PSP);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
	/* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
	hw->tbi_compatibility_on = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	/* Delay to allow any outstanding PCI transactions to complete before
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
	 * resetting the device
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	msleep(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	/* Must reset the PHY before resetting the MAC */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
		ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		msleep(5);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	/* Issue a global reset to the MAC.  This will reset the chip's
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	 * transmit, receive, DMA, and link units.  It will not effect
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	 * the current PCI configuration.  The global reset bit is self-
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
	 * clearing, and should clear within a microsecond.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
	e_dbg("Issuing a global reset to MAC\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
	case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
	case e1000_82540:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	case e1000_82545:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	case e1000_82546:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
	case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
		/* These controllers can't ack the 64-bit write when issuing the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
		 * reset, so use IO-mapping as a workaround to issue the reset */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
		E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	case e1000_82545_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	case e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		/* Reset is performed on a shadow of the control register */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		ew32(CTRL_DUP, (ctrl | E1000_CTRL_RST));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	case e1000_ce4100:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		ew32(CTRL, (ctrl | E1000_CTRL_RST));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	/* After MAC reset, force reload of EEPROM to restore power-on settings to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	 * device.  Later controllers reload the EEPROM automatically, so just wait
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	 * for reload to complete.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	case e1000_82543:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
		/* Wait for reset to complete */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		udelay(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
		ctrl_ext = er32(CTRL_EXT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
		ctrl_ext |= E1000_CTRL_EXT_EE_RST;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		ew32(CTRL_EXT, ctrl_ext);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		/* Wait for EEPROM reload */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
		msleep(2);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	case e1000_82547:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	case e1000_82547_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
		/* Wait for EEPROM reload */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		msleep(20);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
		/* Auto read done will delay 5ms or poll based on mac type */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
		ret_val = e1000_get_auto_rd_done(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	/* Disable HW ARPs on ASF enabled adapters */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	if (hw->mac_type >= e1000_82540) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
		manc = er32(MANC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
		manc &= ~(E1000_MANC_ARP_EN);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
		ew32(MANC, manc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
		e1000_phy_init_script(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
		/* Configure activity LED after PHY reset */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
		led_ctrl = er32(LEDCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
		ew32(LEDCTL, led_ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	/* Clear interrupt mask to stop board from generating interrupts */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	e_dbg("Masking off all interrupts\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	ew32(IMC, 0xffffffff);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	/* Clear any pending interrupt events. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	icr = er32(ICR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	/* If MWI was previously enabled, reenable it. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	if (hw->mac_type == e1000_82542_rev2_0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
		if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
			e1000_pci_set_mwi(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
 * e1000_init_hw: Performs basic configuration of the adapter.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
 * Assumes that the controller has previously been reset and is in a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
 * post-reset uninitialized state. Initializes the receive address registers,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
 * multicast table, and VLAN filter table. Calls routines to setup link
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
 * configuration and flow control settings. Clears all on-chip counters. Leaves
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
 * the transmit and receive units disabled and uninitialized.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
s32 e1000_init_hw(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	u32 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	u32 mta_size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
	u32 ctrl_ext;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	e_dbg("e1000_init_hw");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	/* Initialize Identification LED */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	ret_val = e1000_id_led_init(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
		e_dbg("Error Initializing Identification LED\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
	/* Set the media type and TBI compatibility */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	e1000_set_media_type(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	/* Disabling VLAN filtering. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	e_dbg("Initializing the IEEE VLAN\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	if (hw->mac_type < e1000_82545_rev_3)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
		ew32(VET, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	e1000_clear_vfta(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	if (hw->mac_type == e1000_82542_rev2_0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		e_dbg("Disabling MWI on 82542 rev 2.0\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		e1000_pci_clear_mwi(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		ew32(RCTL, E1000_RCTL_RST);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		msleep(5);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	/* Setup the receive address. This involves initializing all of the Receive
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	 * Address Registers (RARs 0 - 15).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	e1000_init_rx_addrs(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	if (hw->mac_type == e1000_82542_rev2_0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		ew32(RCTL, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		msleep(1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
			e1000_pci_set_mwi(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	/* Zero out the Multicast HASH table */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	e_dbg("Zeroing the MTA\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	mta_size = E1000_MC_TBL_SIZE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	for (i = 0; i < mta_size; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
		/* use write flush to prevent Memory Write Block (MWB) from
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
		 * occurring when accessing our register space */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
	/* Set the PCI priority bit correctly in the CTRL register.  This
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	 * determines if the adapter gives priority to receives, or if it
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	 * gives equal priority to transmits and receives.  Valid only on
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	 * 82542 and 82543 silicon.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
		ew32(CTRL, ctrl | E1000_CTRL_PRIOR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
	case e1000_82545_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	case e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		/* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		if (hw->bus_type == e1000_bus_type_pcix
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		    && e1000_pcix_get_mmrbc(hw) > 2048)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
			e1000_pcix_set_mmrbc(hw, 2048);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	/* Call a subroutine to configure the link and setup flow control. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	ret_val = e1000_setup_link(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	/* Set the transmit descriptor write-back policy */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	if (hw->mac_type > e1000_82544) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
		ctrl = er32(TXDCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
		ctrl =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
		    (ctrl & ~E1000_TXDCTL_WTHRESH) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		    E1000_TXDCTL_FULL_TX_DESC_WB;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		ew32(TXDCTL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	/* Clear all of the statistics registers (clear on read).  It is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	 * important that we do this after we have tried to establish link
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	 * because the symbol error count will increment wildly if there
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	 * is no link.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	e1000_clear_hw_cntrs(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
	    hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
		ctrl_ext = er32(CTRL_EXT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
		/* Relaxed ordering must be disabled to avoid a parity
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
		 * error crash in a PCI slot. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
		ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
		ew32(CTRL_EXT, ctrl_ext);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
 * e1000_adjust_serdes_amplitude - Adjust SERDES output amplitude based on EEPROM setting.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
 * @hw: Struct containing variables accessed by shared code.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	u16 eeprom_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	e_dbg("e1000_adjust_serdes_amplitude");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	if (hw->media_type != e1000_media_type_internal_serdes)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	case e1000_82545_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	case e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	                            &eeprom_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	if (eeprom_data != EEPROM_RESERVED_WORD) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
		/* Adjust SERDES output amplitude only. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
		eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		    e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
 * e1000_setup_link - Configures flow control and link settings.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
 * Determines which flow control settings to use. Calls the appropriate media-
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
 * specific link configuration function. Configures the flow control settings.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
 * Assuming the adapter has a valid link partner, a valid link should be
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
 * established. Assumes the hardware has previously been reset and the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
 * transmitter and receiver are not enabled.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
s32 e1000_setup_link(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	u32 ctrl_ext;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	u16 eeprom_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	e_dbg("e1000_setup_link");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	/* Read and store word 0x0F of the EEPROM. This word contains bits
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	 * that determine the hardware's default PAUSE (flow control) mode,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	 * a bit that determines whether the HW defaults to enabling or
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	 * disabling auto-negotiation, and the direction of the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	 * SW defined pins. If there is no SW over-ride of the flow
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	 * control setting, then the variable hw->fc will
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	 * be initialized based on a value in the EEPROM.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
	if (hw->fc == E1000_FC_DEFAULT) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
		ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
					    1, &eeprom_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
			e_dbg("EEPROM Read Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
			return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
		if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
			hw->fc = E1000_FC_NONE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
		else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
			 EEPROM_WORD0F_ASM_DIR)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
			hw->fc = E1000_FC_TX_PAUSE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
			hw->fc = E1000_FC_FULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	/* We want to save off the original Flow Control configuration just
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	 * in case we get disconnected and then reconnected into a different
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	 * hub or switch with different Flow Control capabilities.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	if (hw->mac_type == e1000_82542_rev2_0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
		hw->fc &= (~E1000_FC_TX_PAUSE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
		hw->fc &= (~E1000_FC_RX_PAUSE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	hw->original_fc = hw->fc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	/* Take the 4 bits from EEPROM word 0x0F that determine the initial
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	 * polarity value for the SW controlled pins, and setup the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	 * Extended Device Control reg with that info.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	 * This is needed because one of the SW controlled pins is used for
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	 * signal detection.  So this should be done before e1000_setup_pcs_link()
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	 * or e1000_phy_setup() is called.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	if (hw->mac_type == e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
		ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
					    1, &eeprom_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
			e_dbg("EEPROM Read Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
			return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
		ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
			    SWDPIO__EXT_SHIFT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
		ew32(CTRL_EXT, ctrl_ext);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	/* Call the necessary subroutine to configure the link. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	ret_val = (hw->media_type == e1000_media_type_copper) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	    e1000_setup_copper_link(hw) : e1000_setup_fiber_serdes_link(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	/* Initialize the flow control address, type, and PAUSE timer
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	 * registers to their default values.  This is done even if flow
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	 * control is disabled, because it does not hurt anything to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	 * initialize these registers.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	e_dbg("Initializing the Flow Control address, type and timer regs\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	ew32(FCT, FLOW_CONTROL_TYPE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
	ew32(FCTTV, hw->fc_pause_time);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
	/* Set the flow control receive threshold registers.  Normally,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
	 * these registers will be set to a default threshold that may be
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	 * adjusted later by the driver's runtime code.  However, if the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	 * ability to transmit pause frames in not enabled, then these
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	 * registers will be set to 0.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	if (!(hw->fc & E1000_FC_TX_PAUSE)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
		ew32(FCRTL, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
		ew32(FCRTH, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
		/* We need to set up the Receive Threshold high and low water marks
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
		 * as well as (optionally) enabling the transmission of XON frames.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
		if (hw->fc_send_xon) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
			ew32(FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
			ew32(FCRTH, hw->fc_high_water);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
			ew32(FCRTL, hw->fc_low_water);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
			ew32(FCRTH, hw->fc_high_water);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
 * e1000_setup_fiber_serdes_link - prepare fiber or serdes link
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
 * Manipulates Physical Coding Sublayer functions in order to configure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
 * link. Assumes the hardware has been previously reset and the transmitter
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
 * and receiver are not enabled.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	u32 status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	u32 txcw = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	u32 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	u32 signal = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	e_dbg("e1000_setup_fiber_serdes_link");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	/* On adapters with a MAC newer than 82544, SWDP 1 will be
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	 * set when the optics detect a signal. On older adapters, it will be
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	 * cleared when there is a signal.  This applies to fiber media only.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	 * If we're on serdes media, adjust the output amplitude to value
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	 * set in the EEPROM.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	if (hw->media_type == e1000_media_type_fiber)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
		signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	ret_val = e1000_adjust_serdes_amplitude(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	/* Take the link out of reset */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	ctrl &= ~(E1000_CTRL_LRST);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	/* Adjust VCO speed to improve BER performance */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	ret_val = e1000_set_vco_speed(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	e1000_config_collision_dist(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	/* Check for a software override of the flow control settings, and setup
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	 * the device accordingly.  If auto-negotiation is enabled, then software
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	 * will have to set the "PAUSE" bits to the correct value in the Tranmsit
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	 * Config Word Register (TXCW) and re-start auto-negotiation.  However, if
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	 * auto-negotiation is disabled, then software will have to manually
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	 * configure the two flow control enable bits in the CTRL register.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	 * The possible values of the "fc" parameter are:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	 *      0:  Flow control is completely disabled
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	 *      1:  Rx flow control is enabled (we can receive pause frames, but
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	 *          not send pause frames).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	 *      2:  Tx flow control is enabled (we can send pause frames but we do
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	 *          not support receiving pause frames).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	switch (hw->fc) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	case E1000_FC_NONE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		/* Flow control is completely disabled by a software over-ride. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	case E1000_FC_RX_PAUSE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
		/* RX Flow control is enabled and TX Flow control is disabled by a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
		 * software over-ride. Since there really isn't a way to advertise
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
		 * that we are capable of RX Pause ONLY, we will advertise that we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
		 * support both symmetric and asymmetric RX PAUSE. Later, we will
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		 *  disable the adapter's ability to send PAUSE frames.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	case E1000_FC_TX_PAUSE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		/* TX Flow control is enabled, and RX Flow control is disabled, by a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
		 * software over-ride.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	case E1000_FC_FULL:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
		/* Flow control (both RX and TX) is enabled by a software over-ride. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
		e_dbg("Flow control param set incorrectly\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
		return -E1000_ERR_CONFIG;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	/* Since auto-negotiation is enabled, take the link out of reset (the link
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	 * will be in reset, because we previously reset the chip). This will
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	 * restart auto-negotiation.  If auto-negotiation is successful then the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	 * link-up status bit will be set and the flow control enable bits (RFCE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	 * and TFCE) will be set according to their negotiated value.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	e_dbg("Auto-negotiation enabled\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	ew32(TXCW, txcw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	hw->txcw = txcw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	msleep(1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	/* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	 * indication in the Device Status Register.  Time-out if a link isn't
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	 * seen in 500 milliseconds seconds (Auto-negotiation should complete in
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	 * less than 500 milliseconds even if the other end is doing it in SW).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	 * For internal serdes, we just assume a signal is present, then poll.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	if (hw->media_type == e1000_media_type_internal_serdes ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	    (er32(CTRL) & E1000_CTRL_SWDPIN1) == signal) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
		e_dbg("Looking for Link\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
		for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
			msleep(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
			status = er32(STATUS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
			if (status & E1000_STATUS_LU)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
		if (i == (LINK_UP_TIMEOUT / 10)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
			e_dbg("Never got a valid link from auto-neg!!!\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
			hw->autoneg_failed = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
			/* AutoNeg failed to achieve a link, so we'll call
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
			 * e1000_check_for_link. This routine will force the link up if
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
			 * we detect a signal. This will allow us to communicate with
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
			 * non-autonegotiating link partners.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
			ret_val = e1000_check_for_link(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
			if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
				e_dbg("Error while checking for link\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
			hw->autoneg_failed = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
			hw->autoneg_failed = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
			e_dbg("Valid Link Found\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
		e_dbg("No Signal Detected\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
 * e1000_copper_link_rtl_setup - Copper link setup for e1000_phy_rtl series.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
 * Commits changes to PHY configuration by calling e1000_phy_reset().
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
static s32 e1000_copper_link_rtl_setup(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	/* SW reset the PHY so all changes take effect */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	ret_val = e1000_phy_reset(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
	if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
		e_dbg("Error Resetting the PHY\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
static s32 gbe_dhg_phy_setup(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	u32 ctrl_aux;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	switch (hw->phy_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	case e1000_phy_8211:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
		ret_val = e1000_copper_link_rtl_setup(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
			e_dbg("e1000_copper_link_rtl_setup failed!\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	case e1000_phy_8201:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		/* Set RMII mode */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		ctrl_aux = er32(CTL_AUX);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
		ctrl_aux |= E1000_CTL_AUX_RMII;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
		ew32(CTL_AUX, ctrl_aux);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
		/* Disable the J/K bits required for receive */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
		ctrl_aux = er32(CTL_AUX);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
		ctrl_aux |= 0x4;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
		ctrl_aux &= ~0x2;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
		ew32(CTL_AUX, ctrl_aux);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		ret_val = e1000_copper_link_rtl_setup(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
			e_dbg("e1000_copper_link_rtl_setup failed!\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
		e_dbg("Error Resetting the PHY\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		return E1000_ERR_PHY_TYPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
 * e1000_copper_link_preconfig - early configuration for copper
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
 * Make sure we have a valid PHY and change PHY mode before link setup.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
static s32 e1000_copper_link_preconfig(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	e_dbg("e1000_copper_link_preconfig");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	/* With 82543, we need to force speed and duplex on the MAC equal to what
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	 * the PHY speed and duplex configuration is. In addition, we need to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	 * perform a hardware reset on the PHY to take it out of reset.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	if (hw->mac_type > e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
		ctrl |= E1000_CTRL_SLU;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
		ctrl |=
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		    (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		ret_val = e1000_phy_hw_reset(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	/* Make sure we have a valid PHY */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	ret_val = e1000_detect_gig_phy(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		e_dbg("Error, did not detect valid phy.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	e_dbg("Phy ID = %x\n", hw->phy_id);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	/* Set PHY to class A mode (if necessary) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	ret_val = e1000_set_phy_mode(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	if ((hw->mac_type == e1000_82545_rev_3) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	    (hw->mac_type == e1000_82546_rev_3)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
		phy_data |= 0x00000008;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	if (hw->mac_type <= e1000_82543 ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	    hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	    hw->mac_type == e1000_82541_rev_2
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	    || hw->mac_type == e1000_82547_rev_2)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
		hw->phy_reset_disable = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
 * e1000_copper_link_igp_setup - Copper link setup for e1000_phy_igp series.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
static s32 e1000_copper_link_igp_setup(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	u32 led_ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	e_dbg("e1000_copper_link_igp_setup");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	if (hw->phy_reset_disable)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	ret_val = e1000_phy_reset(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
		e_dbg("Error Resetting the PHY\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	/* Wait 15ms for MAC to configure PHY from eeprom settings */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	msleep(15);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	/* Configure activity LED after PHY reset */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	led_ctrl = er32(LEDCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	led_ctrl &= IGP_ACTIVITY_LED_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	ew32(LEDCTL, led_ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	/* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	if (hw->phy_type == e1000_phy_igp) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
		/* disable lplu d3 during driver init */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
		ret_val = e1000_set_d3_lplu_state(hw, false);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
			e_dbg("Error Disabling LPLU D3\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
	/* Configure mdi-mdix settings */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		hw->dsp_config_state = e1000_dsp_config_disabled;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
		/* Force MDI for earlier revs of the IGP PHY */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
		phy_data &=
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		    ~(IGP01E1000_PSCR_AUTO_MDIX |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		      IGP01E1000_PSCR_FORCE_MDI_MDIX);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
		hw->mdix = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		hw->dsp_config_state = e1000_dsp_config_enabled;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		switch (hw->mdix) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		case 1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
			phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		case 2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
			phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		case 0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
			phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	/* set auto-master slave resolution settings */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	if (hw->autoneg) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		e1000_ms_type phy_ms_setting = hw->master_slave;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		if (hw->ffe_config_state == e1000_ffe_config_active)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
			hw->ffe_config_state = e1000_ffe_config_enabled;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		if (hw->dsp_config_state == e1000_dsp_config_activated)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
			hw->dsp_config_state = e1000_dsp_config_enabled;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
		/* when autonegotiation advertisement is only 1000Mbps then we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		 * should disable SmartSpeed and enable Auto MasterSlave
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
		 * resolution as hardware default. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		if (hw->autoneg_advertised == ADVERTISE_1000_FULL) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
			/* Disable SmartSpeed */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
					       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
						phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
			/* Set auto Master/Slave resolution process */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
			    e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
			phy_data &= ~CR_1000T_MS_ENABLE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
			    e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		/* load defaults for future use */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
		hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
		    ((phy_data & CR_1000T_MS_VALUE) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		     e1000_ms_force_master :
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		     e1000_ms_force_slave) : e1000_ms_auto;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
		switch (phy_ms_setting) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		case e1000_ms_force_master:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
			phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		case e1000_ms_force_slave:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
			phy_data |= CR_1000T_MS_ENABLE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
			phy_data &= ~(CR_1000T_MS_VALUE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		case e1000_ms_auto:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
			phy_data &= ~CR_1000T_MS_ENABLE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
 * e1000_copper_link_mgp_setup - Copper link setup for e1000_phy_m88 series.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
static s32 e1000_copper_link_mgp_setup(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
	e_dbg("e1000_copper_link_mgp_setup");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
	if (hw->phy_reset_disable)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
	/* Enable CRS on TX. This must be set for half-duplex operation. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	/* Options:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	 *   MDI/MDI-X = 0 (default)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	 *   0 - Auto for all speeds
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	 *   1 - MDI mode
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	 *   2 - MDI-X mode
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
	switch (hw->mdix) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	case 1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
	case 2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
	case 3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	case 0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	/* Options:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	 *   disable_polarity_correction = 0 (default)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	 *       Automatic Correction for Reversed Cable Polarity
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	 *   0 - Disabled
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	 *   1 - Enabled
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	if (hw->disable_polarity_correction == 1)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	if (hw->phy_revision < M88E1011_I_REV_4) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		/* Force TX_CLK in the Extended PHY Specific Control Register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
		 * to 25MHz clock.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
		    e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
				       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
		if ((hw->phy_revision == E1000_REVISION_2) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
		    (hw->phy_id == M88E1111_I_PHY_ID)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
			/* Vidalia Phy, set the downshift counter to 5x */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
			phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
			ret_val = e1000_write_phy_reg(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
						      M88E1000_EXT_PHY_SPEC_CTRL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
						      phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
			/* Configure Master and Slave downshift values */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
				      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
			ret_val = e1000_write_phy_reg(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
						      M88E1000_EXT_PHY_SPEC_CTRL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
						      phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	/* SW Reset the PHY so all changes take effect */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	ret_val = e1000_phy_reset(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
		e_dbg("Error Resetting the PHY\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
 * e1000_copper_link_autoneg - setup auto-neg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
 * Setup auto-negotiation and flow control advertisements,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
 * and then perform auto-negotiation.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	e_dbg("e1000_copper_link_autoneg");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	/* Perform some bounds checking on the hw->autoneg_advertised
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	 * parameter.  If this variable is zero, then set it to the default.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
	hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	/* If autoneg_advertised is zero, we assume it was not defaulted
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	 * by the calling code so we set to advertise full capability.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	if (hw->autoneg_advertised == 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
		hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
	/* IFE/RTL8201N PHY only supports 10/100 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	if (hw->phy_type == e1000_phy_8201)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
		hw->autoneg_advertised &= AUTONEG_ADVERTISE_10_100_ALL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	e_dbg("Reconfiguring auto-neg advertisement params\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
	ret_val = e1000_phy_setup_autoneg(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
		e_dbg("Error Setting up Auto-Negotiation\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	e_dbg("Restarting Auto-Neg\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	 * the Auto Neg Restart bit in the PHY control register.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	/* Does the user want to wait for Auto-Neg to complete here, or
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	 * check at a later time (for example, callback routine).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	if (hw->wait_autoneg_complete) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
		ret_val = e1000_wait_autoneg(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
			e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
			    ("Error while waiting for autoneg to complete\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	hw->get_link_status = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
 * e1000_copper_link_postconfig - post link setup
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
 * Config the MAC and the PHY after link is up.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
 *   1) Set up the MAC to the current PHY speed/duplex
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
 *      if we are on 82543.  If we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
 *      are on newer silicon, we only need to configure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
 *      collision distance in the Transmit Control Register.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
 *   2) Set up flow control on the MAC to that established with
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
 *      the link partner.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
 *   3) Config DSP to improve Gigabit link quality for some PHY revisions.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
static s32 e1000_copper_link_postconfig(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	e_dbg("e1000_copper_link_postconfig");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
	if ((hw->mac_type >= e1000_82544) && (hw->mac_type != e1000_ce4100)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
		e1000_config_collision_dist(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
		ret_val = e1000_config_mac_to_phy(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
			e_dbg("Error configuring MAC to PHY settings\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	ret_val = e1000_config_fc_after_link_up(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
		e_dbg("Error Configuring Flow Control\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
	/* Config DSP to improve Giga link quality */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
	if (hw->phy_type == e1000_phy_igp) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
		ret_val = e1000_config_dsp_after_link_change(hw, true);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
			e_dbg("Error Configuring DSP after link up\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
 * e1000_setup_copper_link - phy/speed/duplex setting
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
 * Detects which PHY is present and sets up the speed and duplex
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
static s32 e1000_setup_copper_link(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	u16 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
	e_dbg("e1000_setup_copper_link");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
	/* Check if it is a valid PHY and set PHY mode if necessary. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	ret_val = e1000_copper_link_preconfig(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	if (hw->phy_type == e1000_phy_igp) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
		ret_val = e1000_copper_link_igp_setup(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
	} else if (hw->phy_type == e1000_phy_m88) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
		ret_val = e1000_copper_link_mgp_setup(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
		ret_val = gbe_dhg_phy_setup(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
			e_dbg("gbe_dhg_phy_setup failed!\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	if (hw->autoneg) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
		/* Setup autoneg and flow control advertisement
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
		 * and perform autonegotiation */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
		ret_val = e1000_copper_link_autoneg(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
		/* PHY will be set to 10H, 10F, 100H,or 100F
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
		 * depending on value from forced_speed_duplex. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		e_dbg("Forcing speed and duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		ret_val = e1000_phy_force_speed_duplex(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
			e_dbg("Error Forcing Speed and Duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	/* Check link status. Wait up to 100 microseconds for link to become
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	 * valid.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	for (i = 0; i < 10; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		if (phy_data & MII_SR_LINK_STATUS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
			/* Config the MAC and PHY after link is up */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
			ret_val = e1000_copper_link_postconfig(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
			e_dbg("Valid link established!!!\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
			return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		udelay(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	e_dbg("Unable to establish link!!!\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
 * e1000_phy_setup_autoneg - phy settings
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
 * Configures PHY autoneg and flow control advertisement settings
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	u16 mii_autoneg_adv_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	u16 mii_1000t_ctrl_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	e_dbg("e1000_phy_setup_autoneg");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
	ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	/* Read the MII 1000Base-T Control Register (Address 9). */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
	else if (hw->phy_type == e1000_phy_8201)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
	/* Need to parse both autoneg_advertised and fc and set up
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	 * the appropriate PHY registers.  First we will parse for
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	 * autoneg_advertised software override.  Since we can advertise
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	 * a plethora of combinations, we need to check each bit
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
	 * individually.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
	 * the  1000Base-T Control Register (Address 9).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
	mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
	mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
	e_dbg("autoneg_advertised %x\n", hw->autoneg_advertised);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
	/* Do we want to advertise 10 Mb Half Duplex? */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
		e_dbg("Advertise 10mb Half duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	/* Do we want to advertise 10 Mb Full Duplex? */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
		e_dbg("Advertise 10mb Full duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	/* Do we want to advertise 100 Mb Half Duplex? */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
	if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
		e_dbg("Advertise 100mb Half duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	/* Do we want to advertise 100 Mb Full Duplex? */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
	if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
		e_dbg("Advertise 100mb Full duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		    ("Advertise 1000mb Half duplex requested, request denied!\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	/* Do we want to advertise 1000 Mb Full Duplex? */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		e_dbg("Advertise 1000mb Full duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	/* Check for a software override of the flow control settings, and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	 * setup the PHY advertisement registers accordingly.  If
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	 * auto-negotiation is enabled, then software will have to set the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	 * "PAUSE" bits to the correct value in the Auto-Negotiation
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
	 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	 * The possible values of the "fc" parameter are:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
	 *      0:  Flow control is completely disabled
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	 *      1:  Rx flow control is enabled (we can receive pause frames
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
	 *          but not send pause frames).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	 *      2:  Tx flow control is enabled (we can send pause frames
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	 *          but we do not support receiving pause frames).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
	 *  other:  No software override.  The flow control configuration
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	 *          in the EEPROM is used.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
	switch (hw->fc) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
	case E1000_FC_NONE:	/* 0 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		/* Flow control (RX & TX) is completely disabled by a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
		 * software over-ride.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	case E1000_FC_RX_PAUSE:	/* 1 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
		/* RX Flow control is enabled, and TX Flow control is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
		 * disabled, by a software over-ride.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		/* Since there really isn't a way to advertise that we are
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		 * capable of RX Pause ONLY, we will advertise that we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		 * support both symmetric and asymmetric RX PAUSE.  Later
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		 * (in e1000_config_fc_after_link_up) we will disable the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
		 *hw's ability to send PAUSE frames.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	case E1000_FC_TX_PAUSE:	/* 2 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		/* TX Flow control is enabled, and RX Flow control is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		 * disabled, by a software over-ride.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
	case E1000_FC_FULL:	/* 3 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
		/* Flow control (both RX and TX) is enabled by a software
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		 * over-ride.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
		e_dbg("Flow control param set incorrectly\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
		return -E1000_ERR_CONFIG;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	if (hw->phy_type == e1000_phy_8201) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
		mii_1000t_ctrl_reg = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		                              mii_1000t_ctrl_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
 * e1000_phy_force_speed_duplex - force link settings
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
 * Force PHY speed and duplex settings to hw->forced_speed_duplex
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	u16 mii_ctrl_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	u16 mii_status_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	u16 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	e_dbg("e1000_phy_force_speed_duplex");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	/* Turn off Flow control if we are forcing speed and duplex. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	hw->fc = E1000_FC_NONE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	e_dbg("hw->fc = %d\n", hw->fc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	/* Read the Device Control Register. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
	/* Set the bits to Force Speed and Duplex in the Device Ctrl Reg. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	ctrl &= ~(DEVICE_SPEED_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	/* Clear the Auto Speed Detect Enable bit. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
	ctrl &= ~E1000_CTRL_ASDE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
	/* Read the MII Control Register. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
	/* We need to disable autoneg in order to force link and duplex. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	/* Are we forcing Full or Half Duplex? */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	if (hw->forced_speed_duplex == e1000_100_full ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	    hw->forced_speed_duplex == e1000_10_full) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
		/* We want to force full duplex so we SET the full duplex bits in the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
		 * Device and MII Control Registers.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		ctrl |= E1000_CTRL_FD;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		mii_ctrl_reg |= MII_CR_FULL_DUPLEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		e_dbg("Full Duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		/* We want to force half duplex so we CLEAR the full duplex bits in
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		 * the Device and MII Control Registers.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		ctrl &= ~E1000_CTRL_FD;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		mii_ctrl_reg &= ~MII_CR_FULL_DUPLEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
		e_dbg("Half Duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
	/* Are we forcing 100Mbps??? */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	if (hw->forced_speed_duplex == e1000_100_full ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	    hw->forced_speed_duplex == e1000_100_half) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		/* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		ctrl |= E1000_CTRL_SPD_100;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		mii_ctrl_reg |= MII_CR_SPEED_100;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		e_dbg("Forcing 100mb ");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		/* Set the 10Mb bit and turn off the 1000Mb and 100Mb bits. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
		mii_ctrl_reg |= MII_CR_SPEED_10;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
		mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
		e_dbg("Forcing 10mb ");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	e1000_config_collision_dist(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
	/* Write the configured values back to the Device Control Reg. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
	if (hw->phy_type == e1000_phy_m88) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
		/* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		 * forced whenever speed are duplex are forced.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
		e_dbg("M88E1000 PSCR: %x\n", phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		/* Need to reset the PHY or these changes will be ignored */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		mii_ctrl_reg |= MII_CR_RESET;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		/* Disable MDI-X support for 10/100 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
		/* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
		 * forced whenever speed or duplex are forced.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
		    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
		phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
		    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
	/* Write back the modified PHY MII control register. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
	udelay(1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
	/* The wait_autoneg_complete flag may be a little misleading here.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	 * Since we are forcing speed and duplex, Auto-Neg is not enabled.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	 * But we do want to delay for a period while forcing only so we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	 * don't generate false No Link messages.  So we will wait here
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	 * only if the user has set wait_autoneg_complete to 1, which is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	 * the default.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	if (hw->wait_autoneg_complete) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
		/* We will wait for autoneg to complete. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
		e_dbg("Waiting for forced speed/duplex link.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
		mii_status_reg = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		/* We will wait for autoneg to complete or 4.5 seconds to expire. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
		for (i = PHY_FORCE_TIME; i > 0; i--) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
			/* Read the MII Status Register and wait for Auto-Neg Complete bit
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
			 * to be set.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
			if (mii_status_reg & MII_SR_LINK_STATUS)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
			msleep(100);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		if ((i == 0) && (hw->phy_type == e1000_phy_m88)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
			/* We didn't get link.  Reset the DSP and wait again for link. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
			ret_val = e1000_phy_reset_dsp(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
			if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
				e_dbg("Error Resetting PHY DSP\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		/* This loop will early-out if the link condition has been met.  */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
		for (i = PHY_FORCE_TIME; i > 0; i--) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
			if (mii_status_reg & MII_SR_LINK_STATUS)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
			msleep(100);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
			/* Read the MII Status Register and wait for Auto-Neg Complete bit
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
			 * to be set.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	if (hw->phy_type == e1000_phy_m88) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
		/* Because we reset the PHY above, we need to re-force TX_CLK in the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		 * Extended PHY Specific Control Register to 25MHz clock.  This value
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		 * defaults back to a 2.5MHz clock when the PHY is reset.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
		    e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
				       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
		    e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
					phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
		/* In addition, because of the s/w reset above, we need to enable CRS on
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
		 * TX.  This must be set for both full and half duplex operation.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
		if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
		    && (!hw->autoneg)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
		    && (hw->forced_speed_duplex == e1000_10_full
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
			|| hw->forced_speed_duplex == e1000_10_half)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
			ret_val = e1000_polarity_reversal_workaround(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
 * e1000_config_collision_dist - set collision distance register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
 * Sets the collision distance in the Transmit Control register.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
 * Link should have been established previously. Reads the speed and duplex
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
 * information from the Device Status register.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
void e1000_config_collision_dist(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	u32 tctl, coll_dist;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	e_dbg("e1000_config_collision_dist");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
	if (hw->mac_type < e1000_82543)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
		coll_dist = E1000_COLLISION_DISTANCE_82542;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
		coll_dist = E1000_COLLISION_DISTANCE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
	tctl = er32(TCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	tctl &= ~E1000_TCTL_COLD;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	tctl |= coll_dist << E1000_COLD_SHIFT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	ew32(TCTL, tctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
 * e1000_config_mac_to_phy - sync phy and mac settings
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
 * @mii_reg: data to write to the MII control register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
 * Sets MAC speed and duplex settings to reflect the those in the PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
 * The contents of the PHY register containing the needed information need to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
 * be passed in.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	e_dbg("e1000_config_mac_to_phy");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	/* 82544 or newer MAC, Auto Speed Detection takes care of
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	 * MAC speed/duplex configuration.*/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
	if ((hw->mac_type >= e1000_82544) && (hw->mac_type != e1000_ce4100))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	/* Read the Device Control Register and set the bits to Force Speed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	 * and Duplex.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
	ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	switch (hw->phy_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	case e1000_phy_8201:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
		ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
		if (phy_data & RTL_PHY_CTRL_FD)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
			ctrl |= E1000_CTRL_FD;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
			ctrl &= ~E1000_CTRL_FD;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
		if (phy_data & RTL_PHY_CTRL_SPD_100)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
			ctrl |= E1000_CTRL_SPD_100;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
			ctrl |= E1000_CTRL_SPD_10;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
		e1000_config_collision_dist(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
		/* Set up duplex in the Device Control and Transmit Control
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
		 * registers depending on negotiated values.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
		                             &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
		if (phy_data & M88E1000_PSSR_DPLX)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
			ctrl |= E1000_CTRL_FD;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
			ctrl &= ~E1000_CTRL_FD;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
		e1000_config_collision_dist(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
		/* Set up speed in the Device Control register depending on
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		 * negotiated values.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
		if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
			ctrl |= E1000_CTRL_SPD_1000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
		else if ((phy_data & M88E1000_PSSR_SPEED) ==
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
		         M88E1000_PSSR_100MBS)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
			ctrl |= E1000_CTRL_SPD_100;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	/* Write the configured values back to the Device Control Reg. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
 * e1000_force_mac_fc - force flow control settings
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
 * Forces the MAC's flow control settings.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
 * Sets the TFCE and RFCE bits in the device control register to reflect
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
 * the adapter settings. TFCE and RFCE need to be explicitly set by
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
 * software when a Copper PHY is used because autonegotiation is managed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
 * by the PHY rather than the MAC. Software must also configure these
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
 * bits when link is forced on a fiber connection.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
s32 e1000_force_mac_fc(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
	e_dbg("e1000_force_mac_fc");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	/* Get the current configuration of the Device Control Register */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	/* Because we didn't get link via the internal auto-negotiation
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	 * mechanism (we either forced link or we got link via PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	 * auto-neg), we have to manually enable/disable transmit an
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	 * receive flow control.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	 * The "Case" statement below enables/disable flow control
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	 * according to the "hw->fc" parameter.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
	 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
	 * The possible values of the "fc" parameter are:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	 *      0:  Flow control is completely disabled
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
	 *      1:  Rx flow control is enabled (we can receive pause
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	 *          frames but not send pause frames).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
	 *      2:  Tx flow control is enabled (we can send pause frames
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
	 *          frames but we do not receive pause frames).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
	 *      3:  Both Rx and TX flow control (symmetric) is enabled.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
	 *  other:  No other values should be possible at this point.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
	switch (hw->fc) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
	case E1000_FC_NONE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	case E1000_FC_RX_PAUSE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
		ctrl &= (~E1000_CTRL_TFCE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		ctrl |= E1000_CTRL_RFCE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	case E1000_FC_TX_PAUSE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
		ctrl &= (~E1000_CTRL_RFCE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
		ctrl |= E1000_CTRL_TFCE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	case E1000_FC_FULL:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
		e_dbg("Flow control param set incorrectly\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
		return -E1000_ERR_CONFIG;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	/* Disable TX Flow Control for 82542 (rev 2.0) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	if (hw->mac_type == e1000_82542_rev2_0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
		ctrl &= (~E1000_CTRL_TFCE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
 * e1000_config_fc_after_link_up - configure flow control after autoneg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
 * Configures flow control settings after link is established
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
 * Should be called immediately after a valid link has been established.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
 * Forces MAC flow control settings if link was forced. When in MII/GMII mode
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
 * and autonegotiation is enabled, the MAC flow control settings will be set
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
 * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
 * and RFCE bits will be automatically set to the negotiated flow control mode.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	u16 mii_status_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	u16 mii_nway_adv_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	u16 mii_nway_lp_ability_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	u16 speed;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	u16 duplex;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
	e_dbg("e1000_config_fc_after_link_up");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
	/* Check for the case where we have fiber media and auto-neg failed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	 * so we had to force link.  In this case, we need to force the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	 * configuration of the MAC to match the "fc" parameter.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	    || ((hw->media_type == e1000_media_type_internal_serdes)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
		&& (hw->autoneg_failed))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	    || ((hw->media_type == e1000_media_type_copper)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
		&& (!hw->autoneg))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
		ret_val = e1000_force_mac_fc(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
			e_dbg("Error forcing flow control settings\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	/* Check for the case where we have copper media and auto-neg is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
	 * enabled.  In this case, we need to check and see if Auto-Neg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
	 * has completed, and if so, how the PHY and link partner has
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
	 * flow control configured.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
	if ((hw->media_type == e1000_media_type_copper) && hw->autoneg) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
		/* Read the MII Status Register and check to see if AutoNeg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
		 * has completed.  We read this twice because this reg has
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
		 * some "sticky" (latched) bits.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
		if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
			/* The AutoNeg process has completed, so we now need to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
			 * read both the Auto Negotiation Advertisement Register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
			 * (Address 4) and the Auto_Negotiation Base Page Ability
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
			 * Register (Address 5) to determine how flow control was
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
			 * negotiated.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
			ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
						     &mii_nway_adv_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
			ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
						     &mii_nway_lp_ability_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
			/* Two bits in the Auto Negotiation Advertisement Register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
			 * (Address 4) and two bits in the Auto Negotiation Base
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
			 * Page Ability Register (Address 5) determine flow control
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
			 * for both the PHY and the link partner.  The following
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
			 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
			 * 1999, describes these PAUSE resolution bits and how flow
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
			 * control is determined based upon these settings.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
			 * NOTE:  DC = Don't Care
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
			 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
			 *   LOCAL DEVICE  |   LINK PARTNER
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			 *-------|---------|-------|---------|--------------------
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
			 *   0   |    0    |  DC   |   DC    | E1000_FC_NONE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
			 *   0   |    1    |   0   |   DC    | E1000_FC_NONE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
			 *   0   |    1    |   1   |    0    | E1000_FC_NONE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
			 *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
			 *   1   |    0    |   0   |   DC    | E1000_FC_NONE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
			 *   1   |    1    |   0   |    0    | E1000_FC_NONE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
			 *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
			 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
			/* Are both PAUSE bits set to 1?  If so, this implies
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
			 * Symmetric Flow Control is enabled at both ends.  The
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
			 * ASM_DIR bits are irrelevant per the spec.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
			 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
			 * For Symmetric Flow Control:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
			 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
			 *   LOCAL DEVICE  |   LINK PARTNER
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
			 *-------|---------|-------|---------|--------------------
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
			 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
			if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
			    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
				/* Now we need to check if the user selected RX ONLY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
				 * of pause frames.  In this case, we had to advertise
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
				 * FULL flow control because we could not advertise RX
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
				 * ONLY. Hence, we must now check to see if we need to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
				 * turn OFF  the TRANSMISSION of PAUSE frames.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
				 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
				if (hw->original_fc == E1000_FC_FULL) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
					hw->fc = E1000_FC_FULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
					e_dbg("Flow Control = FULL.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
				} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
					hw->fc = E1000_FC_RX_PAUSE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
					e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
					    ("Flow Control = RX PAUSE frames only.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
				}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
			/* For receiving PAUSE frames ONLY.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
			 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
			 *   LOCAL DEVICE  |   LINK PARTNER
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
			 *-------|---------|-------|---------|--------------------
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
			 *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
			 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
			else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
				 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
			{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
				hw->fc = E1000_FC_TX_PAUSE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
				e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
				    ("Flow Control = TX PAUSE frames only.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
			/* For transmitting PAUSE frames ONLY.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
			 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
			 *   LOCAL DEVICE  |   LINK PARTNER
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
			 *-------|---------|-------|---------|--------------------
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
			 *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
			 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
			else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
				 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
			{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
				hw->fc = E1000_FC_RX_PAUSE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
				e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
				    ("Flow Control = RX PAUSE frames only.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
			/* Per the IEEE spec, at this point flow control should be
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
			 * disabled.  However, we want to consider that we could
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
			 * be connected to a legacy switch that doesn't advertise
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
			 * desired flow control, but can be forced on the link
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
			 * partner.  So if we advertised no flow control, that is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
			 * what we will resolve to.  If we advertised some kind of
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
			 * receive capability (Rx Pause Only or Full Flow Control)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
			 * and the link partner advertised none, we will configure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
			 * ourselves to enable Rx Flow Control only.  We can do
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
			 * this safely for two reasons:  If the link partner really
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
			 * didn't want flow control enabled, and we enable Rx, no
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
			 * harm done since we won't be receiving any PAUSE frames
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
			 * anyway.  If the intent on the link partner was to have
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
			 * flow control enabled, then by us enabling RX only, we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
			 * can at least receive pause frames and process them.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
			 * This is a good idea because in most cases, since we are
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
			 * predominantly a server NIC, more times than not we will
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
			 * be asked to delay transmission of packets than asking
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
			 * our link partner to pause transmission of frames.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
			else if ((hw->original_fc == E1000_FC_NONE ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
				  hw->original_fc == E1000_FC_TX_PAUSE) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
				 hw->fc_strict_ieee) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
				hw->fc = E1000_FC_NONE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
				e_dbg("Flow Control = NONE.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
				hw->fc = E1000_FC_RX_PAUSE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
				e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
				    ("Flow Control = RX PAUSE frames only.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
			/* Now we need to do one last check...  If we auto-
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
			 * negotiated to HALF DUPLEX, flow control should not be
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
			 * enabled per IEEE 802.3 spec.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
			if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
				e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
				    ("Error getting link speed and duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
			if (duplex == HALF_DUPLEX)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
				hw->fc = E1000_FC_NONE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
			/* Now we call a subroutine to actually force the MAC
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
			 * controller to use the correct flow control settings.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
			ret_val = e1000_force_mac_fc(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
			if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
				e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
				    ("Error forcing flow control settings\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
			e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
			    ("Copper PHY and Auto Neg has not completed.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
 * e1000_check_for_serdes_link_generic - Check for link (Serdes)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
 * @hw: pointer to the HW structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
 * Checks for link up on the hardware.  If link is not up and we have
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
 * a signal, then we need to force link up.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
static s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	u32 rxcw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	u32 status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	s32 ret_val = E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	e_dbg("e1000_check_for_serdes_link_generic");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
	status = er32(STATUS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
	rxcw = er32(RXCW);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
	/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	 * If we don't have link (auto-negotiation failed or link partner
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	 * cannot auto-negotiate), and our link partner is not trying to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
	 * auto-negotiate with us (we are receiving idles or data),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	 * we need to force link up. We also need to give auto-negotiation
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	 * time to complete.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
		if (hw->autoneg_failed == 0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
			hw->autoneg_failed = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
			goto out;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
		e_dbg("NOT RXing /C/, disable AutoNeg and force link.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
		/* Disable auto-negotiation in the TXCW register */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
		/* Force link-up and also force full-duplex. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
		ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
		ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
		/* Configure Flow Control after forcing link up. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
		ret_val = e1000_config_fc_after_link_up(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
			e_dbg("Error configuring flow control\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
			goto out;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
		/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		 * If we are forcing link and we are receiving /C/ ordered
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
		 * sets, re-enable auto-negotiation in the TXCW register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
		 * and disable forced link in the Device Control register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
		 * in an attempt to auto-negotiate with our link partner.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
		e_dbg("RXing /C/, enable AutoNeg and stop forcing link.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
		ew32(TXCW, hw->txcw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
		hw->serdes_has_link = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
		/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
		 * If we force link for non-auto-negotiation switch, check
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
		 * link status based on MAC synchronization for internal
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
		 * serdes media type.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
		/* SYNCH bit and IV bit are sticky. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
		udelay(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
		rxcw = er32(RXCW);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
		if (rxcw & E1000_RXCW_SYNCH) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
			if (!(rxcw & E1000_RXCW_IV)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
				hw->serdes_has_link = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
				e_dbg("SERDES: Link up - forced.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
			hw->serdes_has_link = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
			e_dbg("SERDES: Link down - force failed.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
	if (E1000_TXCW_ANE & er32(TXCW)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
		status = er32(STATUS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
		if (status & E1000_STATUS_LU) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
			/* SYNCH bit and IV bit are sticky, so reread rxcw. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
			udelay(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
			rxcw = er32(RXCW);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
			if (rxcw & E1000_RXCW_SYNCH) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
				if (!(rxcw & E1000_RXCW_IV)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
					hw->serdes_has_link = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
					e_dbg("SERDES: Link up - autoneg "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
						 "completed successfully.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
				} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
					hw->serdes_has_link = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
					e_dbg("SERDES: Link down - invalid"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
						 "codewords detected in autoneg.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
				}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
				hw->serdes_has_link = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
				e_dbg("SERDES: Link down - no sync.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
			hw->serdes_has_link = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
			e_dbg("SERDES: Link down - autoneg failed\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
      out:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
	return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
 * e1000_check_for_link
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
 * Checks to see if the link status of the hardware has changed.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
 * Called by any function that needs to check the link status of the adapter.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
s32 e1000_check_for_link(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	u32 rxcw = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	u32 status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
	u32 rctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	u32 icr;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	u32 signal = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
	e_dbg("e1000_check_for_link");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
	ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	status = er32(STATUS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	/* On adapters with a MAC newer than 82544, SW Definable pin 1 will be
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
	 * set when the optics detect a signal. On older adapters, it will be
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	 * cleared when there is a signal.  This applies to fiber media only.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	if ((hw->media_type == e1000_media_type_fiber) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	    (hw->media_type == e1000_media_type_internal_serdes)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
		rxcw = er32(RXCW);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
		if (hw->media_type == e1000_media_type_fiber) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
			signal =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
			    (hw->mac_type >
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
			     e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
			if (status & E1000_STATUS_LU)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
				hw->get_link_status = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
	/* If we have a copper PHY then we only want to go out to the PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	 * registers to see if Auto-Neg has completed and/or if our link
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
	 * status has changed.  The get_link_status flag will be set if we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	 * receive a Link Status Change interrupt or we have Rx Sequence
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	 * Errors.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		/* First we want to see if the MII Status Register reports
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
		 * link.  If so, then we want to get the current speed/duplex
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		 * of the PHY.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
		 * Read the register twice since the link bit is sticky.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
		if (phy_data & MII_SR_LINK_STATUS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
			hw->get_link_status = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
			/* Check if there was DownShift, must be checked immediately after
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
			 * link-up */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
			e1000_check_downshift(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
			/* If we are on 82544 or 82543 silicon and speed/duplex
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
			 * are forced to 10H or 10F, then we will implement the polarity
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
			 * reversal workaround.  We disable interrupts first, and upon
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
			 * returning, place the devices interrupt state to its previous
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
			 * value except for the link status change interrupt which will
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
			 * happen due to the execution of this workaround.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
			if ((hw->mac_type == e1000_82544
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
			     || hw->mac_type == e1000_82543) && (!hw->autoneg)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
			    && (hw->forced_speed_duplex == e1000_10_full
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
				|| hw->forced_speed_duplex == e1000_10_half)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
				ew32(IMC, 0xffffffff);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
				ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
				    e1000_polarity_reversal_workaround(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
				icr = er32(ICR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
				ew32(ICS, (icr & ~E1000_ICS_LSC));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
				ew32(IMS, IMS_ENABLE_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
			/* No link detected */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
			e1000_config_dsp_after_link_change(hw, false);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
			return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		/* If we are forcing speed/duplex, then we simply return since
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
		 * we have already determined whether we have link or not.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
		if (!hw->autoneg)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
			return -E1000_ERR_CONFIG;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
		/* optimize the dsp settings for the igp phy */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
		e1000_config_dsp_after_link_change(hw, true);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		/* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		 * have Si on board that is 82544 or newer, Auto
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
		 * Speed Detection takes care of MAC speed/duplex
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		 * configuration.  So we only need to configure Collision
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
		 * Distance in the MAC.  Otherwise, we need to force
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		 * speed/duplex on the MAC to the current PHY speed/duplex
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
		 * settings.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
		if ((hw->mac_type >= e1000_82544) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
		    (hw->mac_type != e1000_ce4100))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
			e1000_config_collision_dist(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
		else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
			ret_val = e1000_config_mac_to_phy(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
			if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
				e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
				    ("Error configuring MAC to PHY settings\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
		/* Configure Flow Control now that Auto-Neg has completed. First, we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		 * need to restore the desired flow control settings because we may
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		 * have had to re-autoneg with a different link partner.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		ret_val = e1000_config_fc_after_link_up(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			e_dbg("Error configuring flow control\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
		/* At this point we know that we are on copper and we have
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
		 * auto-negotiated link.  These are conditions for checking the link
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
		 * partner capability register.  We use the link speed to determine if
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
		 * TBI compatibility needs to be turned on or off.  If the link is not
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
		 * at gigabit speed, then TBI compatibility is not needed.  If we are
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
		 * at gigabit speed, we turn on TBI compatibility.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
		if (hw->tbi_compatibility_en) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
			u16 speed, duplex;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
			if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
				e_dbg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
				    ("Error getting link speed and duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
			if (speed != SPEED_1000) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
				/* If link speed is not set to gigabit speed, we do not need
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
				 * to enable TBI compatibility.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
				 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
				if (hw->tbi_compatibility_on) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
					/* If we previously were in the mode, turn it off. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
					rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
					rctl &= ~E1000_RCTL_SBP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
					ew32(RCTL, rctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
					hw->tbi_compatibility_on = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
				}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
				/* If TBI compatibility is was previously off, turn it on. For
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
				 * compatibility with a TBI link partner, we will store bad
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
				 * packets. Some frames have an additional byte on the end and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
				 * will look like CRC errors to to the hardware.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
				 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
				if (!hw->tbi_compatibility_on) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
					hw->tbi_compatibility_on = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
					rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
					rctl |= E1000_RCTL_SBP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
					ew32(RCTL, rctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
				}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
	if ((hw->media_type == e1000_media_type_fiber) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
	    (hw->media_type == e1000_media_type_internal_serdes))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
		e1000_check_for_serdes_link_generic(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
 * e1000_get_speed_and_duplex
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
 * @speed: Speed of the connection
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
 * @duplex: Duplex setting of the connection
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
 * Detects the current speed and duplex settings of the hardware.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
	u32 status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
	e_dbg("e1000_get_speed_and_duplex");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
	if (hw->mac_type >= e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
		status = er32(STATUS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
		if (status & E1000_STATUS_SPEED_1000) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
			*speed = SPEED_1000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
			e_dbg("1000 Mbs, ");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
		} else if (status & E1000_STATUS_SPEED_100) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
			*speed = SPEED_100;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
			e_dbg("100 Mbs, ");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
			*speed = SPEED_10;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
			e_dbg("10 Mbs, ");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		if (status & E1000_STATUS_FD) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
			*duplex = FULL_DUPLEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
			e_dbg("Full Duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
			*duplex = HALF_DUPLEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
			e_dbg(" Half Duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
		e_dbg("1000 Mbs, Full Duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
		*speed = SPEED_1000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
		*duplex = FULL_DUPLEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	/* IGP01 PHY may advertise full duplex operation after speed downgrade even
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	 * if it is operating at half duplex.  Here we set the duplex settings to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	 * match the duplex in the link partner's capabilities.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
		ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
		if (!(phy_data & NWAY_ER_LP_NWAY_CAPS))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
			*duplex = HALF_DUPLEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
		else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
			    e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
			if ((*speed == SPEED_100
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
			     && !(phy_data & NWAY_LPAR_100TX_FD_CAPS))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
			    || (*speed == SPEED_10
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
				&& !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
				*duplex = HALF_DUPLEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
 * e1000_wait_autoneg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
 * Blocks until autoneg completes or times out (~4.5 seconds)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
static s32 e1000_wait_autoneg(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	u16 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
	e_dbg("e1000_wait_autoneg");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	e_dbg("Waiting for Auto-Neg to complete.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	/* We will wait for autoneg to complete or 4.5 seconds to expire. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
		/* Read the MII Status Register and wait for Auto-Neg
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
		 * Complete bit to be set.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
		if (phy_data & MII_SR_AUTONEG_COMPLETE) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
			return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
		msleep(100);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
 * e1000_raise_mdi_clk - Raises the Management Data Clock
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
 * @ctrl: Device control register's current value
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	/* Raise the clock input to the Management Data Clock (by setting the MDC
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	 * bit), and then delay 10 microseconds.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
	ew32(CTRL, (*ctrl | E1000_CTRL_MDC));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
	udelay(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
 * e1000_lower_mdi_clk - Lowers the Management Data Clock
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
 * @ctrl: Device control register's current value
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
	/* Lower the clock input to the Management Data Clock (by clearing the MDC
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
	 * bit), and then delay 10 microseconds.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	ew32(CTRL, (*ctrl & ~E1000_CTRL_MDC));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
	udelay(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
 * e1000_shift_out_mdi_bits - Shifts data bits out to the PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
 * @data: Data to send out to the PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
 * @count: Number of bits to shift out
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
 * Bits are shifted out in MSB to LSB order.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data, u16 count)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
	u32 mask;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	/* We need to shift "count" number of bits out to the PHY. So, the value
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
	 * in the "data" parameter will be shifted out to the PHY one bit at a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
	 * time. In order to do this, "data" must be broken down into bits.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
	mask = 0x01;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
	mask <<= (count - 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
	/* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
	ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	while (mask) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
		/* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
		 * then raising and lowering the Management Data Clock. A "0" is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
		 * shifted out to the PHY by setting the MDIO bit to "0" and then
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
		 * raising and lowering the clock.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
		if (data & mask)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
			ctrl |= E1000_CTRL_MDIO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
			ctrl &= ~E1000_CTRL_MDIO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
		ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
		udelay(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
		e1000_raise_mdi_clk(hw, &ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
		e1000_lower_mdi_clk(hw, &ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
		mask = mask >> 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
 * e1000_shift_in_mdi_bits - Shifts data bits in from the PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
 * Bits are shifted in in MSB to LSB order.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	u16 data = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
	u8 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	/* In order to read a register from the PHY, we need to shift in a total
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	 * of 18 bits from the PHY. The first two bit (turnaround) times are used
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
	 * to avoid contention on the MDIO pin when a read operation is performed.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	 * These two bits are ignored by us and thrown away. Bits are "shifted in"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	 * by raising the input to the Management Data Clock (setting the MDC bit),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
	 * and then reading the value of the MDIO bit.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
	/* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	ctrl &= ~E1000_CTRL_MDIO_DIR;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
	ctrl &= ~E1000_CTRL_MDIO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
	ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
	/* Raise and Lower the clock before reading in the data. This accounts for
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
	 * the turnaround bits. The first clock occurred when we clocked out the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
	 * last bit of the Register Address.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	e1000_raise_mdi_clk(hw, &ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
	e1000_lower_mdi_clk(hw, &ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	for (data = 0, i = 0; i < 16; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
		data = data << 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
		e1000_raise_mdi_clk(hw, &ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
		/* Check to see if we shifted in a "1". */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		if (ctrl & E1000_CTRL_MDIO)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
			data |= 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
		e1000_lower_mdi_clk(hw, &ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
	e1000_raise_mdi_clk(hw, &ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
	e1000_lower_mdi_clk(hw, &ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
	return data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
 * e1000_read_phy_reg - read a phy register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
 * @reg_addr: address of the PHY register to read
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
 * Reads the value from a PHY register, if the value is on a specific non zero
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
 * page, sets the page first.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
	u32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
	e_dbg("e1000_read_phy_reg");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
	if ((hw->phy_type == e1000_phy_igp) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
						 (u16) reg_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
	ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
					phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
				 u16 *phy_data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
	u32 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	u32 mdic = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
	const u32 phy_addr = (hw->mac_type == e1000_ce4100) ? hw->phy_addr : 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
	e_dbg("e1000_read_phy_reg_ex");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
		e_dbg("PHY Address %d is out of range\n", reg_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
		return -E1000_ERR_PARAM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
	if (hw->mac_type > e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
		/* Set up Op-code, Phy Address, and register address in the MDI
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
		 * Control register.  The MAC will take care of interfacing with the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
		 * PHY to retrieve the desired data.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
		if (hw->mac_type == e1000_ce4100) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
			mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
				(INTEL_CE_GBE_MDIC_OP_READ) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
				(INTEL_CE_GBE_MDIC_GO));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
			writel(mdic, E1000_MDIO_CMD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
			/* Poll the ready bit to see if the MDI read
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
			 * completed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
			for (i = 0; i < 64; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
				udelay(50);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
				mdic = readl(E1000_MDIO_CMD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
				if (!(mdic & INTEL_CE_GBE_MDIC_GO))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
					break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
			if (mdic & INTEL_CE_GBE_MDIC_GO) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
				e_dbg("MDI Read did not complete\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
				return -E1000_ERR_PHY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
			mdic = readl(E1000_MDIO_STS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
			if (mdic & INTEL_CE_GBE_MDIC_READ_ERROR) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
				e_dbg("MDI Read Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
				return -E1000_ERR_PHY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
			*phy_data = (u16) mdic;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
			mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
				(E1000_MDIC_OP_READ));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
			ew32(MDIC, mdic);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
			/* Poll the ready bit to see if the MDI read
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
			 * completed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
			for (i = 0; i < 64; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
				udelay(50);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
				mdic = er32(MDIC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
				if (mdic & E1000_MDIC_READY)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
					break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
			if (!(mdic & E1000_MDIC_READY)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
				e_dbg("MDI Read did not complete\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
				return -E1000_ERR_PHY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
			if (mdic & E1000_MDIC_ERROR) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
				e_dbg("MDI Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
				return -E1000_ERR_PHY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
			*phy_data = (u16) mdic;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		/* We must first send a preamble through the MDIO pin to signal the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		 * beginning of an MII instruction.  This is done by sending 32
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		 * consecutive "1" bits.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
		/* Now combine the next few fields that are required for a read
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
		 * operation.  We use this method instead of calling the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
		 * e1000_shift_out_mdi_bits routine five different times. The format of
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
		 * a MII read instruction consists of a shift out of 14 bits and is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
		 * defined as follows:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		 *    <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		 * followed by a shift in of 18 bits.  This first two bits shifted in
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		 * are TurnAround bits used to avoid contention on the MDIO pin when a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		 * READ operation is performed.  These two bits are thrown away
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		 * followed by a shift in of 16 bits which contains the desired data.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
		mdic = ((reg_addr) | (phy_addr << 5) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
			(PHY_OP_READ << 10) | (PHY_SOF << 12));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
		e1000_shift_out_mdi_bits(hw, mdic, 14);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
		/* Now that we've shifted out the read command to the MII, we need to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
		 * "shift in" the 16-bit value (18 total bits) of the requested PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
		 * register address.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		*phy_data = e1000_shift_in_mdi_bits(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
 * e1000_write_phy_reg - write a phy register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
 * @reg_addr: address of the PHY register to write
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
 * @data: data to write to the PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
 * Writes a value to a PHY register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
	u32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
	e_dbg("e1000_write_phy_reg");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
	if ((hw->phy_type == e1000_phy_igp) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
						 (u16) reg_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
	ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
					 phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
	return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
				  u16 phy_data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
	u32 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
	u32 mdic = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
	const u32 phy_addr = (hw->mac_type == e1000_ce4100) ? hw->phy_addr : 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	e_dbg("e1000_write_phy_reg_ex");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
		e_dbg("PHY Address %d is out of range\n", reg_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
		return -E1000_ERR_PARAM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	if (hw->mac_type > e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
		/* Set up Op-code, Phy Address, register address, and data
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
		 * intended for the PHY register in the MDI Control register.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
		 * The MAC will take care of interfacing with the PHY to send
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
		 * the desired data.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
		if (hw->mac_type == e1000_ce4100) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
			mdic = (((u32) phy_data) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
				(reg_addr << E1000_MDIC_REG_SHIFT) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
				(INTEL_CE_GBE_MDIC_OP_WRITE) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
				(INTEL_CE_GBE_MDIC_GO));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
			writel(mdic, E1000_MDIO_CMD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
			/* Poll the ready bit to see if the MDI read
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
			 * completed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
			for (i = 0; i < 640; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
				udelay(5);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
				mdic = readl(E1000_MDIO_CMD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
				if (!(mdic & INTEL_CE_GBE_MDIC_GO))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
					break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
			if (mdic & INTEL_CE_GBE_MDIC_GO) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
				e_dbg("MDI Write did not complete\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
				return -E1000_ERR_PHY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
			mdic = (((u32) phy_data) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
				(reg_addr << E1000_MDIC_REG_SHIFT) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
				(E1000_MDIC_OP_WRITE));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
			ew32(MDIC, mdic);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
			/* Poll the ready bit to see if the MDI read
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
			 * completed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
			for (i = 0; i < 641; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
				udelay(5);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
				mdic = er32(MDIC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
				if (mdic & E1000_MDIC_READY)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
					break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
			if (!(mdic & E1000_MDIC_READY)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
				e_dbg("MDI Write did not complete\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
				return -E1000_ERR_PHY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
		/* We'll need to use the SW defined pins to shift the write command
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
		 * out to the PHY. We first send a preamble to the PHY to signal the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		 * beginning of the MII instruction.  This is done by sending 32
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		 * consecutive "1" bits.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
		/* Now combine the remaining required fields that will indicate a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
		 * write operation. We use this method instead of calling the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
		 * e1000_shift_out_mdi_bits routine for each field in the command. The
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
		 * format of a MII write instruction is as follows:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
		 * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
		mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
			(PHY_OP_WRITE << 12) | (PHY_SOF << 14));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
		mdic <<= 16;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		mdic |= (u32) phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
		e1000_shift_out_mdi_bits(hw, mdic, 32);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
 * e1000_phy_hw_reset - reset the phy, hardware style
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
 * Returns the PHY to the power-on reset state
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
s32 e1000_phy_hw_reset(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
	u32 ctrl, ctrl_ext;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	u32 led_ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	e_dbg("e1000_phy_hw_reset");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	e_dbg("Resetting Phy...\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	if (hw->mac_type > e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
		/* Read the device control register and assert the E1000_CTRL_PHY_RST
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
		 * bit. Then, take it out of reset.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
		 * For e1000 hardware, we delay for 10ms between the assert
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
		 * and deassert.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
		ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
		ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
		msleep(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
		/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
		 * bit to put the PHY into reset. Then, take it out of reset.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		ctrl_ext = er32(CTRL_EXT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
		ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
		ew32(CTRL_EXT, ctrl_ext);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
		msleep(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
		ew32(CTRL_EXT, ctrl_ext);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	udelay(150);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
		/* Configure activity LED after PHY reset */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
		led_ctrl = er32(LEDCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
		ew32(LEDCTL, led_ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
	/* Wait for FW to finish PHY configuration. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
	ret_val = e1000_get_phy_cfg_done(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
	if (ret_val != E1000_SUCCESS)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
 * e1000_phy_reset - reset the phy to commit settings
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
 * Resets the PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
 * Sets bit 15 of the MII Control register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
s32 e1000_phy_reset(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	e_dbg("e1000_phy_reset");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
	switch (hw->phy_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	case e1000_phy_igp:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
		ret_val = e1000_phy_hw_reset(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		phy_data |= MII_CR_RESET;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
		ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
		udelay(1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	if (hw->phy_type == e1000_phy_igp)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
		e1000_phy_init_script(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
 * e1000_detect_gig_phy - check the phy type
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
 * Probes the expected PHY address for known PHY IDs
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
static s32 e1000_detect_gig_phy(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	s32 phy_init_status, ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	u16 phy_id_high, phy_id_low;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	bool match = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	e_dbg("e1000_detect_gig_phy");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	if (hw->phy_id != 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	/* Read the PHY ID Registers to identify which PHY is onboard. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	hw->phy_id = (u32) (phy_id_high << 16);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	udelay(20);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	hw->phy_id |= (u32) (phy_id_low & PHY_REVISION_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	hw->phy_revision = (u32) phy_id_low & ~PHY_REVISION_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	case e1000_82543:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
		if (hw->phy_id == M88E1000_E_PHY_ID)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
			match = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
		if (hw->phy_id == M88E1000_I_PHY_ID)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
			match = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	case e1000_82540:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	case e1000_82545:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	case e1000_82545_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	case e1000_82546:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	case e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
		if (hw->phy_id == M88E1011_I_PHY_ID)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
			match = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	case e1000_ce4100:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
		if ((hw->phy_id == RTL8211B_PHY_ID) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
		    (hw->phy_id == RTL8201N_PHY_ID) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
		    (hw->phy_id == M88E1118_E_PHY_ID))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
			match = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
	case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	case e1000_82547:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	case e1000_82547_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
		if (hw->phy_id == IGP01E1000_I_PHY_ID)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
			match = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
		e_dbg("Invalid MAC type %d\n", hw->mac_type);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
		return -E1000_ERR_CONFIG;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	phy_init_status = e1000_set_phy_type(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	if ((match) && (phy_init_status == E1000_SUCCESS)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
		e_dbg("PHY ID 0x%X detected\n", hw->phy_id);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	e_dbg("Invalid PHY ID 0x%X\n", hw->phy_id);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	return -E1000_ERR_PHY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
 * e1000_phy_reset_dsp - reset DSP
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
 * Resets the PHY's DSP
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	e_dbg("e1000_phy_reset_dsp");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	do {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
		ret_val = e1000_write_phy_reg(hw, 29, 0x001d);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
		ret_val = e1000_write_phy_reg(hw, 30, 0x00c1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
		ret_val = e1000_write_phy_reg(hw, 30, 0x0000);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
		ret_val = E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	} while (0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
	return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
 * e1000_phy_igp_get_info - get igp specific registers
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
 * @phy_info: PHY information structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
 * Get PHY information from various PHY registers for igp PHY only.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
				  struct e1000_phy_info *phy_info)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	u16 phy_data, min_length, max_length, average;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	e1000_rev_polarity polarity;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	e_dbg("e1000_phy_igp_get_info");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	/* The downshift status is checked only once, after link is established,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	 * and it stored in the hw->speed_downgraded parameter. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	phy_info->downshift = (e1000_downshift) hw->speed_downgraded;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	/* IGP01E1000 does not need to support it. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
	phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	/* IGP01E1000 always correct polarity reversal */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	phy_info->polarity_correction = e1000_polarity_reversal_enabled;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	/* Check polarity status */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	ret_val = e1000_check_polarity(hw, &polarity);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	phy_info->cable_polarity = polarity;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	phy_info->mdix_mode =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	    (e1000_auto_x_mode) ((phy_data & IGP01E1000_PSSR_MDIX) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
				 IGP01E1000_PSSR_MDIX_SHIFT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
		/* Local/Remote Receiver Information are only valid at 1000 Mbps */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
		phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
		/* Get cable length */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
		ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
		/* Translate to old method */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
		average = (max_length + min_length) / 2;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
		if (average <= e1000_igp_cable_length_50)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
			phy_info->cable_length = e1000_cable_length_50;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		else if (average <= e1000_igp_cable_length_80)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
			phy_info->cable_length = e1000_cable_length_50_80;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
		else if (average <= e1000_igp_cable_length_110)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
			phy_info->cable_length = e1000_cable_length_80_110;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
		else if (average <= e1000_igp_cable_length_140)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
			phy_info->cable_length = e1000_cable_length_110_140;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
			phy_info->cable_length = e1000_cable_length_140;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
 * e1000_phy_m88_get_info - get m88 specific registers
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
 * @phy_info: PHY information structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
 * Get PHY information from various PHY registers for m88 PHY only.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
				  struct e1000_phy_info *phy_info)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	e1000_rev_polarity polarity;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
	e_dbg("e1000_phy_m88_get_info");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
	/* The downshift status is checked only once, after link is established,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
	 * and it stored in the hw->speed_downgraded parameter. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
	phy_info->downshift = (e1000_downshift) hw->speed_downgraded;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	phy_info->extended_10bt_distance =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	    ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	     M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	    e1000_10bt_ext_dist_enable_lower :
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	    e1000_10bt_ext_dist_enable_normal;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	phy_info->polarity_correction =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	    ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	     M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	    e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	/* Check polarity status */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
	ret_val = e1000_check_polarity(hw, &polarity);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
	phy_info->cable_polarity = polarity;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	phy_info->mdix_mode =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
	    (e1000_auto_x_mode) ((phy_data & M88E1000_PSSR_MDIX) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
				 M88E1000_PSSR_MDIX_SHIFT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
		/* Cable Length Estimation and Local/Remote Receiver Information
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
		 * are only valid at 1000 Mbps.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
		phy_info->cable_length =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
		    (e1000_cable_length) ((phy_data &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
					   M88E1000_PSSR_CABLE_LENGTH) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
					  M88E1000_PSSR_CABLE_LENGTH_SHIFT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
		phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
 * e1000_phy_get_info - request phy info
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
 * @phy_info: PHY information structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
 * Get PHY information from various PHY registers
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
s32 e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	e_dbg("e1000_phy_get_info");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	phy_info->cable_length = e1000_cable_length_undefined;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	phy_info->cable_polarity = e1000_rev_polarity_undefined;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	phy_info->downshift = e1000_downshift_undefined;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	phy_info->polarity_correction = e1000_polarity_reversal_undefined;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	phy_info->mdix_mode = e1000_auto_x_mode_undefined;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	phy_info->local_rx = e1000_1000t_rx_status_undefined;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
	phy_info->remote_rx = e1000_1000t_rx_status_undefined;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	if (hw->media_type != e1000_media_type_copper) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
		e_dbg("PHY info is only valid for copper media\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
		return -E1000_ERR_CONFIG;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
	if ((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
		e_dbg("PHY info is only valid if link is up\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		return -E1000_ERR_CONFIG;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
	if (hw->phy_type == e1000_phy_igp)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
		return e1000_phy_igp_get_info(hw, phy_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
	else if ((hw->phy_type == e1000_phy_8211) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	         (hw->phy_type == e1000_phy_8201))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
		return e1000_phy_m88_get_info(hw, phy_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
s32 e1000_validate_mdi_setting(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
	e_dbg("e1000_validate_mdi_settings");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	if (!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
		e_dbg("Invalid MDI setting detected\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
		hw->mdix = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
		return -E1000_ERR_CONFIG;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
 * e1000_init_eeprom_params - initialize sw eeprom vars
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
 * Sets up eeprom variables in the hw struct.  Must be called after mac_type
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
 * is configured.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
s32 e1000_init_eeprom_params(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
	u32 eecd = er32(EECD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	s32 ret_val = E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	u16 eeprom_size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
	e_dbg("e1000_init_eeprom_params");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
	case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
	case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
	case e1000_82543:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
	case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
		eeprom->type = e1000_eeprom_microwire;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
		eeprom->word_size = 64;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
		eeprom->opcode_bits = 3;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
		eeprom->address_bits = 6;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
		eeprom->delay_usec = 50;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	case e1000_82540:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
	case e1000_82545:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	case e1000_82545_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	case e1000_82546:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	case e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
		eeprom->type = e1000_eeprom_microwire;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
		eeprom->opcode_bits = 3;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
		eeprom->delay_usec = 50;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
		if (eecd & E1000_EECD_SIZE) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
			eeprom->word_size = 256;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
			eeprom->address_bits = 8;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
			eeprom->word_size = 64;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
			eeprom->address_bits = 6;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
	case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
	case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
	case e1000_82547:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
	case e1000_82547_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
		if (eecd & E1000_EECD_TYPE) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
			eeprom->type = e1000_eeprom_spi;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
			eeprom->opcode_bits = 8;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
			eeprom->delay_usec = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
			if (eecd & E1000_EECD_ADDR_BITS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
				eeprom->page_size = 32;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
				eeprom->address_bits = 16;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
				eeprom->page_size = 8;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
				eeprom->address_bits = 8;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
			eeprom->type = e1000_eeprom_microwire;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
			eeprom->opcode_bits = 3;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
			eeprom->delay_usec = 50;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
			if (eecd & E1000_EECD_ADDR_BITS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
				eeprom->word_size = 256;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
				eeprom->address_bits = 8;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
				eeprom->word_size = 64;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
				eeprom->address_bits = 6;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
	if (eeprom->type == e1000_eeprom_spi) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		/* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		 * 32KB (incremented by powers of 2).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
		/* Set to default value for initial eeprom read. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
		eeprom->word_size = 64;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
		ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
		eeprom_size =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
		    (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
		/* 256B eeprom size was not supported in earlier hardware, so we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
		 * bump eeprom_size up one to ensure that "1" (which maps to 256B)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
		 * is never the result used in the shifting logic below. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
		if (eeprom_size)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
			eeprom_size++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
		eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
	return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
 * e1000_raise_ee_clk - Raises the EEPROM's clock input.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
 * @eecd: EECD's current value
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	/* Raise the clock input to the EEPROM (by setting the SK bit), and then
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
	 * wait <delay> microseconds.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
	*eecd = *eecd | E1000_EECD_SK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	ew32(EECD, *eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
	udelay(hw->eeprom.delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
 * e1000_lower_ee_clk - Lowers the EEPROM's clock input.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
 * @eecd: EECD's current value
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	 * wait 50 microseconds.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
	*eecd = *eecd & ~E1000_EECD_SK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
	ew32(EECD, *eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
	udelay(hw->eeprom.delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
 * e1000_shift_out_ee_bits - Shift data bits out to the EEPROM.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
 * @data: data to send to the EEPROM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
 * @count: number of bits to shift out
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data, u16 count)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	u32 eecd;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	u32 mask;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
	/* We need to shift "count" bits out to the EEPROM. So, value in the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	 * "data" parameter will be shifted out to the EEPROM one bit at a time.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	 * In order to do this, "data" must be broken down into bits.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	mask = 0x01 << (count - 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
	eecd = er32(EECD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	if (eeprom->type == e1000_eeprom_microwire) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
		eecd &= ~E1000_EECD_DO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	} else if (eeprom->type == e1000_eeprom_spi) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
		eecd |= E1000_EECD_DO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	do {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
		 * and then raising and then lowering the clock (the SK bit controls
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
		 * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
		 * by setting "DI" to "0" and then raising and then lowering the clock.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
		eecd &= ~E1000_EECD_DI;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
		if (data & mask)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
			eecd |= E1000_EECD_DI;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
		udelay(eeprom->delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
		e1000_raise_ee_clk(hw, &eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
		e1000_lower_ee_clk(hw, &eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
		mask = mask >> 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
	} while (mask);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
	/* We leave the "DI" bit set to "0" when we leave this routine. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
	eecd &= ~E1000_EECD_DI;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
	ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
 * e1000_shift_in_ee_bits - Shift data bits in from the EEPROM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
 * @count: number of bits to shift in
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
	u32 eecd;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
	u32 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
	u16 data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
	/* In order to read a register from the EEPROM, we need to shift 'count'
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
	 * bits in from the EEPROM. Bits are "shifted in" by raising the clock
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
	 * input to the EEPROM (setting the SK bit), and then reading the value of
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
	 * the "DO" bit.  During this "shifting in" process the "DI" bit should
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	 * always be clear.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
	eecd = er32(EECD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
	data = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
	for (i = 0; i < count; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
		data = data << 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
		e1000_raise_ee_clk(hw, &eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
		eecd = er32(EECD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
		eecd &= ~(E1000_EECD_DI);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
		if (eecd & E1000_EECD_DO)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
			data |= 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
		e1000_lower_ee_clk(hw, &eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
	return data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
 * e1000_acquire_eeprom - Prepares EEPROM for access
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
 * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
 * function should be called before issuing a command to the EEPROM.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
static s32 e1000_acquire_eeprom(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
	u32 eecd, i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	e_dbg("e1000_acquire_eeprom");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
	eecd = er32(EECD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
	/* Request EEPROM Access */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
	if (hw->mac_type > e1000_82544) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
		eecd |= E1000_EECD_REQ;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
		eecd = er32(EECD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
		while ((!(eecd & E1000_EECD_GNT)) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		       (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
			i++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
			udelay(5);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
			eecd = er32(EECD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
		if (!(eecd & E1000_EECD_GNT)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
			eecd &= ~E1000_EECD_REQ;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
			ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
			e_dbg("Could not acquire EEPROM grant\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
			return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
	/* Setup EEPROM for Read/Write */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	if (eeprom->type == e1000_eeprom_microwire) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		/* Clear SK and DI */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
		/* Set CS */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
		eecd |= E1000_EECD_CS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
	} else if (eeprom->type == e1000_eeprom_spi) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
		/* Clear SK and CS */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
		udelay(1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
 * e1000_standby_eeprom - Returns EEPROM to a "standby" state
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
static void e1000_standby_eeprom(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	u32 eecd;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	eecd = er32(EECD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
	if (eeprom->type == e1000_eeprom_microwire) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
		udelay(eeprom->delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
		/* Clock high */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
		eecd |= E1000_EECD_SK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
		udelay(eeprom->delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
		/* Select EEPROM */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
		eecd |= E1000_EECD_CS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
		udelay(eeprom->delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
		/* Clock low */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		eecd &= ~E1000_EECD_SK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
		udelay(eeprom->delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	} else if (eeprom->type == e1000_eeprom_spi) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
		/* Toggle CS to flush commands */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
		eecd |= E1000_EECD_CS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
		udelay(eeprom->delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
		eecd &= ~E1000_EECD_CS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
		udelay(eeprom->delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
 * e1000_release_eeprom - drop chip select
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
 * Terminates a command by inverting the EEPROM's chip select pin
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
static void e1000_release_eeprom(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
	u32 eecd;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
	e_dbg("e1000_release_eeprom");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
	eecd = er32(EECD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
	if (hw->eeprom.type == e1000_eeprom_spi) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
		eecd |= E1000_EECD_CS;	/* Pull CS high */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
		eecd &= ~E1000_EECD_SK;	/* Lower SCK */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
		udelay(hw->eeprom.delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	} else if (hw->eeprom.type == e1000_eeprom_microwire) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
		/* cleanup eeprom */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
		/* CS on Microwire is active-high */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
		/* Rising edge of clock */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
		eecd |= E1000_EECD_SK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
		udelay(hw->eeprom.delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
		/* Falling edge of clock */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		eecd &= ~E1000_EECD_SK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
		udelay(hw->eeprom.delay_usec);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
	/* Stop requesting EEPROM access */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
	if (hw->mac_type > e1000_82544) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
		eecd &= ~E1000_EECD_REQ;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
		ew32(EECD, eecd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
 * e1000_spi_eeprom_ready - Reads a 16 bit word from the EEPROM.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
	u16 retry_count = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
	u8 spi_stat_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	e_dbg("e1000_spi_eeprom_ready");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	/* Read "Status Register" repeatedly until the LSB is cleared.  The
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
	 * EEPROM will signal that the command has been completed by clearing
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
	 * bit 0 of the internal status register.  If it's not cleared within
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
	 * 5 milliseconds, then error out.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
	retry_count = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	do {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
		e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
					hw->eeprom.opcode_bits);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
		spi_stat_reg = (u8) e1000_shift_in_ee_bits(hw, 8);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
		if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
		udelay(5);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
		retry_count += 5;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
		e1000_standby_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
	} while (retry_count < EEPROM_MAX_RETRY_SPI);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
	/* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	 * only 0-5mSec on 5V devices)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	if (retry_count >= EEPROM_MAX_RETRY_SPI) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
		e_dbg("SPI EEPROM Status error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
		return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
 * e1000_read_eeprom - Reads a 16 bit word from the EEPROM.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
 * @offset: offset of  word in the EEPROM to read
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
 * @data: word read from the EEPROM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
 * @words: number of words to read
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
	s32 ret;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
	spin_lock(&e1000_eeprom_lock);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
	ret = e1000_do_read_eeprom(hw, offset, words, data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
	spin_unlock(&e1000_eeprom_lock);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
	return ret;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
				u16 *data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
	u32 i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
	e_dbg("e1000_read_eeprom");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
	if (hw->mac_type == e1000_ce4100) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
		GBE_CONFIG_FLASH_READ(GBE_CONFIG_BASE_VIRT, offset, words,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
		                      data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
	/* If eeprom is not yet detected, do so now */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	if (eeprom->word_size == 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
		e1000_init_eeprom_params(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
	/* A check for invalid values:  offset too large, too many words, and not
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
	 * enough words.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
	if ((offset >= eeprom->word_size)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
	    || (words > eeprom->word_size - offset) || (words == 0)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
		e_dbg("\"words\" parameter out of bounds. Words = %d,"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
		      "size = %d\n", offset, eeprom->word_size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
		return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	/* EEPROM's that don't use EERD to read require us to bit-bang the SPI
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
	 * directly. In this case, we need to acquire the EEPROM so that
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	 * FW or other port software does not interrupt.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
	/* Prepare the EEPROM for bit-bang reading */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
		return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
	/* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
	 * acquired the EEPROM at this point, so any returns should release it */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
	if (eeprom->type == e1000_eeprom_spi) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
		u16 word_in;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
		u8 read_opcode = EEPROM_READ_OPCODE_SPI;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
		if (e1000_spi_eeprom_ready(hw)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
			e1000_release_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
			return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
		e1000_standby_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
		/* Some SPI eeproms use the 8th address bit embedded in the opcode */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
		if ((eeprom->address_bits == 8) && (offset >= 128))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
			read_opcode |= EEPROM_A8_OPCODE_SPI;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
		/* Send the READ command (opcode + addr)  */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
		e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
		e1000_shift_out_ee_bits(hw, (u16) (offset * 2),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
					eeprom->address_bits);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
		/* Read the data.  The address of the eeprom internally increments with
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		 * each byte (spi) being read, saving on the overhead of eeprom setup
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
		 * and tear-down.  The address counter will roll over if reading beyond
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
		 * the size of the eeprom, thus allowing the entire memory to be read
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
		 * starting from any offset. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
		for (i = 0; i < words; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
			word_in = e1000_shift_in_ee_bits(hw, 16);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
			data[i] = (word_in >> 8) | (word_in << 8);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
	} else if (eeprom->type == e1000_eeprom_microwire) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
		for (i = 0; i < words; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
			/* Send the READ command (opcode + addr)  */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
			e1000_shift_out_ee_bits(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
						EEPROM_READ_OPCODE_MICROWIRE,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
						eeprom->opcode_bits);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
			e1000_shift_out_ee_bits(hw, (u16) (offset + i),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
						eeprom->address_bits);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
			/* Read the data.  For microwire, each word requires the overhead
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
			 * of eeprom setup and tear-down. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
			data[i] = e1000_shift_in_ee_bits(hw, 16);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
			e1000_standby_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
	/* End this read operation */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
	e1000_release_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
 * e1000_validate_eeprom_checksum - Verifies that the EEPROM has a valid checksum
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
 * Reads the first 64 16 bit words of the EEPROM and sums the values read.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
 * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
 * valid.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
	u16 checksum = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
	u16 i, eeprom_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
	e_dbg("e1000_validate_eeprom_checksum");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
		if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
			e_dbg("EEPROM Read Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
			return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
		checksum += eeprom_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
#ifdef CONFIG_PARISC
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	/* This is a signature and not a checksum on HP c8000 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
	if ((hw->subsystem_vendor_id == 0x103C) && (eeprom_data == 0x16d6))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
#endif
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
	if (checksum == (u16) EEPROM_SUM)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
	else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
		e_dbg("EEPROM Checksum Invalid\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
		return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
 * e1000_update_eeprom_checksum - Calculates/writes the EEPROM checksum
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
 * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
 * Writes the difference to word offset 63 of the EEPROM.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
s32 e1000_update_eeprom_checksum(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
	u16 checksum = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
	u16 i, eeprom_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
	e_dbg("e1000_update_eeprom_checksum");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
	for (i = 0; i < EEPROM_CHECKSUM_REG; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
		if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
			e_dbg("EEPROM Read Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
			return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		checksum += eeprom_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
	checksum = (u16) EEPROM_SUM - checksum;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
	if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
		e_dbg("EEPROM Write Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
		return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
 * e1000_write_eeprom - write words to the different EEPROM types.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
 * @offset: offset within the EEPROM to be written to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
 * @words: number of words to write
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
 * @data: 16 bit word to be written to the EEPROM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
 * If e1000_update_eeprom_checksum is not called after this function, the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
 * EEPROM will most likely contain an invalid checksum.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
	s32 ret;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
	spin_lock(&e1000_eeprom_lock);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
	ret = e1000_do_write_eeprom(hw, offset, words, data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
	spin_unlock(&e1000_eeprom_lock);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
	return ret;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
				 u16 *data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	s32 status = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	e_dbg("e1000_write_eeprom");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
	if (hw->mac_type == e1000_ce4100) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
		GBE_CONFIG_FLASH_WRITE(GBE_CONFIG_BASE_VIRT, offset, words,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
		                       data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
	/* If eeprom is not yet detected, do so now */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
	if (eeprom->word_size == 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
		e1000_init_eeprom_params(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
	/* A check for invalid values:  offset too large, too many words, and not
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
	 * enough words.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
	if ((offset >= eeprom->word_size)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	    || (words > eeprom->word_size - offset) || (words == 0)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		e_dbg("\"words\" parameter out of bounds\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
		return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
	/* Prepare the EEPROM for writing  */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
		return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
	if (eeprom->type == e1000_eeprom_microwire) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
		status = e1000_write_eeprom_microwire(hw, offset, words, data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
		status = e1000_write_eeprom_spi(hw, offset, words, data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
		msleep(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
	/* Done with writing */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
	e1000_release_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
	return status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
 * e1000_write_eeprom_spi - Writes a 16 bit word to a given offset in an SPI EEPROM.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
 * @offset: offset within the EEPROM to be written to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
 * @words: number of words to write
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
 * @data: pointer to array of 8 bit words to be written to the EEPROM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset, u16 words,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
				  u16 *data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
	u16 widx = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
	e_dbg("e1000_write_eeprom_spi");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
	while (widx < words) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
		u8 write_opcode = EEPROM_WRITE_OPCODE_SPI;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
		if (e1000_spi_eeprom_ready(hw))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
			return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
		e1000_standby_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
		/*  Send the WRITE ENABLE command (8 bit opcode )  */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
		e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
					eeprom->opcode_bits);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
		e1000_standby_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
		/* Some SPI eeproms use the 8th address bit embedded in the opcode */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
		if ((eeprom->address_bits == 8) && (offset >= 128))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
			write_opcode |= EEPROM_A8_OPCODE_SPI;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		/* Send the Write command (8-bit opcode + addr) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
		e1000_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		e1000_shift_out_ee_bits(hw, (u16) ((offset + widx) * 2),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
					eeprom->address_bits);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
		/* Send the data */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
		/* Loop to allow for up to whole page write (32 bytes) of eeprom */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
		while (widx < words) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
			u16 word_out = data[widx];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
			word_out = (word_out >> 8) | (word_out << 8);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
			e1000_shift_out_ee_bits(hw, word_out, 16);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
			widx++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
			/* Some larger eeprom sizes are capable of a 32-byte PAGE WRITE
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
			 * operation, while the smaller eeproms are capable of an 8-byte
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
			 * PAGE WRITE operation.  Break the inner loop to pass new address
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
			 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
			if ((((offset + widx) * 2) % eeprom->page_size) == 0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
				e1000_standby_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
 * e1000_write_eeprom_microwire - Writes a 16 bit word to a given offset in a Microwire EEPROM.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
 * @offset: offset within the EEPROM to be written to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
 * @words: number of words to write
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
 * @data: pointer to array of 8 bit words to be written to the EEPROM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
					u16 words, u16 *data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
	u32 eecd;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
	u16 words_written = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
	u16 i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
	e_dbg("e1000_write_eeprom_microwire");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
	/* Send the write enable command to the EEPROM (3-bit opcode plus
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
	 * 6/8-bit dummy address beginning with 11).  It's less work to include
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
	 * the 11 of the dummy address as part of the opcode than it is to shift
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
	 * it over the correct number of bits for the address.  This puts the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
	 * EEPROM into write/erase mode.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
	e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
				(u16) (eeprom->opcode_bits + 2));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
	/* Prepare the EEPROM */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	e1000_standby_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
	while (words_written < words) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
		/* Send the Write command (3-bit opcode + addr) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
		e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
					eeprom->opcode_bits);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
		e1000_shift_out_ee_bits(hw, (u16) (offset + words_written),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
					eeprom->address_bits);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
		/* Send the data */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
		e1000_shift_out_ee_bits(hw, data[words_written], 16);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
		/* Toggle the CS line.  This in effect tells the EEPROM to execute
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
		 * the previous command.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
		e1000_standby_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
		/* Read DO repeatedly until it is high (equal to '1').  The EEPROM will
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
		 * signal that the command has been completed by raising the DO signal.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
		 * If DO does not go high in 10 milliseconds, then error out.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
		for (i = 0; i < 200; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
			eecd = er32(EECD);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
			if (eecd & E1000_EECD_DO)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
			udelay(50);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
		if (i == 200) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
			e_dbg("EEPROM Write did not complete\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
			return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
		/* Recover from write */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
		e1000_standby_eeprom(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
		words_written++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	/* Send the write disable command to the EEPROM (3-bit opcode plus
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
	 * 6/8-bit dummy address beginning with 10).  It's less work to include
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	 * the 10 of the dummy address as part of the opcode than it is to shift
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
	 * it over the correct number of bits for the address.  This takes the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
	 * EEPROM out of write/erase mode.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
	e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
				(u16) (eeprom->opcode_bits + 2));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
 * e1000_read_mac_addr - read the adapters MAC from eeprom
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
 * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
 * second function of dual function devices
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
s32 e1000_read_mac_addr(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
	u16 offset;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
	u16 eeprom_data, i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
	e_dbg("e1000_read_mac_addr");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
	for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
		offset = i >> 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
		if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
			e_dbg("EEPROM Read Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
			return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
		hw->perm_mac_addr[i] = (u8) (eeprom_data & 0x00FF);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
		hw->perm_mac_addr[i + 1] = (u8) (eeprom_data >> 8);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
	case e1000_82546:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	case e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
			hw->perm_mac_addr[5] ^= 0x01;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	for (i = 0; i < NODE_ADDRESS_SIZE; i++)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		hw->mac_addr[i] = hw->perm_mac_addr[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
 * e1000_init_rx_addrs - Initializes receive address filters.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
 * Places the MAC address in receive address register 0 and clears the rest
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
 * of the receive address registers. Clears the multicast table. Assumes
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
 * the receiver is in reset when the routine is called.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
static void e1000_init_rx_addrs(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
	u32 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
	u32 rar_num;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	e_dbg("e1000_init_rx_addrs");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
	/* Setup the receive address. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
	e_dbg("Programming MAC Address into RAR[0]\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
	e1000_rar_set(hw, hw->mac_addr, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
	rar_num = E1000_RAR_ENTRIES;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
	/* Zero out the other 15 receive addresses. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
	e_dbg("Clearing RAR[1-15]\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
	for (i = 1; i < rar_num; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
		E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
 * e1000_hash_mc_addr - Hashes an address to determine its location in the multicast table
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
 * @mc_addr: the multicast address to hash
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
	u32 hash_value = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
	/* The portion of the address that is used for the hash table is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
	 * determined by the mc_filter_type setting.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
	switch (hw->mc_filter_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
		/* [0] [1] [2] [3] [4] [5]
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
		 * 01  AA  00  12  34  56
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
		 * LSB                 MSB
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
	case 0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
		/* [47:36] i.e. 0x563 for above example address */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
		hash_value = ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
	case 1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		/* [46:35] i.e. 0xAC6 for above example address */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
		hash_value = ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
	case 2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
		/* [45:34] i.e. 0x5D8 for above example address */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
		hash_value = ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
	case 3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
		/* [43:32] i.e. 0x634 for above example address */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
		hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
	hash_value &= 0xFFF;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
	return hash_value;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
 * e1000_rar_set - Puts an ethernet address into a receive address register.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
 * @addr: Address to put into receive address register
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
 * @index: Receive address register to write
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	u32 rar_low, rar_high;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
	/* HW expects these in little endian so we reverse the byte order
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
	 * from network order (big endian) to little endian
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
	rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
		   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
	/* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
	 * unit hang.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
	 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
	 * Description:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
	 * If there are any Rx frames queued up or otherwise present in the HW
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
	 * before RSS is enabled, and then we enable RSS, the HW Rx unit will
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
	 * hang.  To work around this issue, we have to disable receives and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
	 * flush out all Rx frames before we enable RSS. To do so, we modify we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	 * redirect all Rx traffic to manageability and then reset the HW.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
	 * This flushes away Rx frames, and (since the redirections to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
	 * manageability persists across resets) keeps new ones from coming in
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
	 * while we work.  Then, we clear the Address Valid AV bit for all MAC
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
	 * addresses and undo the re-direction to manageability.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
	 * Now, frames are coming in again, but the MAC won't accept them, so
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
	 * far so good.  We now proceed to initialize RSS (if necessary) and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
	 * configure the Rx unit.  Last, we re-enable the AV bits and continue
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	 * on our merry way.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
		/* Indicate to hardware the Address is Valid. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
		rar_high |= E1000_RAH_AV;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
	E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
 * e1000_write_vfta - Writes a value to the specified offset in the VLAN filter table.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
 * @offset: Offset in VLAN filer table to write
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
 * @value: Value to write into VLAN filter table
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
	u32 temp;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
	if ((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
		temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
		E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
 * e1000_clear_vfta - Clears the VLAN filer table
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
static void e1000_clear_vfta(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
	u32 offset;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
	u32 vfta_value = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
	u32 vfta_offset = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
	u32 vfta_bit_in_reg = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		/* If the offset we want to clear is the same offset of the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		 * manageability VLAN ID, then clear all bits except that of the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
		 * manageability unit */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
		vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
static s32 e1000_id_led_init(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
	u32 ledctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	const u32 ledctl_mask = 0x000000FF;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
	u16 eeprom_data, i, temp;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	const u16 led_mask = 0x0F;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
	e_dbg("e1000_id_led_init");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
	if (hw->mac_type < e1000_82540) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
		/* Nothing to do */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
	ledctl = er32(LEDCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
	hw->ledctl_default = ledctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	hw->ledctl_mode1 = hw->ledctl_default;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
	hw->ledctl_mode2 = hw->ledctl_default;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
	if (e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		e_dbg("EEPROM Read Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
		return -E1000_ERR_EEPROM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
	if ((eeprom_data == ID_LED_RESERVED_0000) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
	    (eeprom_data == ID_LED_RESERVED_FFFF)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
		eeprom_data = ID_LED_DEFAULT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
	for (i = 0; i < 4; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
		temp = (eeprom_data >> (i << 2)) & led_mask;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
		switch (temp) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
		case ID_LED_ON1_DEF2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
		case ID_LED_ON1_ON2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
		case ID_LED_ON1_OFF2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
			hw->ledctl_mode1 |= ledctl_on << (i << 3);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
		case ID_LED_OFF1_DEF2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
		case ID_LED_OFF1_ON2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
		case ID_LED_OFF1_OFF2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
			hw->ledctl_mode1 |= ledctl_off << (i << 3);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
		default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
			/* Do nothing */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		switch (temp) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
		case ID_LED_DEF1_ON2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
		case ID_LED_ON1_ON2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
		case ID_LED_OFF1_ON2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
			hw->ledctl_mode2 |= ledctl_on << (i << 3);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
		case ID_LED_DEF1_OFF2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
		case ID_LED_ON1_OFF2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
		case ID_LED_OFF1_OFF2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
			hw->ledctl_mode2 |= ledctl_off << (i << 3);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
		default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
			/* Do nothing */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
 * e1000_setup_led
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
 * Prepares SW controlable LED for use and saves the current state of the LED.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
s32 e1000_setup_led(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
	u32 ledctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
	s32 ret_val = E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	e_dbg("e1000_setup_led");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
	case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	case e1000_82543:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
	case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
		/* No setup necessary */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
	case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
	case e1000_82547:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
	case e1000_82547_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
		/* Turn off PHY Smart Power Down (if enabled) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
					     &hw->phy_spd_default);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
					      (u16) (hw->phy_spd_default &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
						     ~IGP01E1000_GMII_SPD));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
		/* Fall Through */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
		if (hw->media_type == e1000_media_type_fiber) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
			ledctl = er32(LEDCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
			/* Save current LEDCTL settings */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
			hw->ledctl_default = ledctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
			/* Turn off LED0 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
			ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
				    E1000_LEDCTL_LED0_BLINK |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
				    E1000_LEDCTL_LED0_MODE_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
			ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
				   E1000_LEDCTL_LED0_MODE_SHIFT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
			ew32(LEDCTL, ledctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
		} else if (hw->media_type == e1000_media_type_copper)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
			ew32(LEDCTL, hw->ledctl_mode1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
 * e1000_cleanup_led - Restores the saved state of the SW controlable LED.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
s32 e1000_cleanup_led(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	s32 ret_val = E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	e_dbg("e1000_cleanup_led");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
	case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
	case e1000_82543:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
	case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
		/* No cleanup necessary */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
	case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	case e1000_82547:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
	case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
	case e1000_82547_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
		/* Turn on PHY Smart Power Down (if previously enabled) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
					      hw->phy_spd_default);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
		/* Fall Through */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		/* Restore LEDCTL settings */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
		ew32(LEDCTL, hw->ledctl_default);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
 * e1000_led_on - Turns on the software controllable LED
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
s32 e1000_led_on(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
	u32 ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
	e_dbg("e1000_led_on");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
	case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
	case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
	case e1000_82543:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
		/* Set SW Defineable Pin 0 to turn on the LED */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
		ctrl |= E1000_CTRL_SWDPIN0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
		ctrl |= E1000_CTRL_SWDPIO0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
	case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
		if (hw->media_type == e1000_media_type_fiber) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
			/* Set SW Defineable Pin 0 to turn on the LED */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
			ctrl |= E1000_CTRL_SWDPIN0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
			ctrl |= E1000_CTRL_SWDPIO0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
			/* Clear SW Defineable Pin 0 to turn on the LED */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
			ctrl &= ~E1000_CTRL_SWDPIN0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
			ctrl |= E1000_CTRL_SWDPIO0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
		if (hw->media_type == e1000_media_type_fiber) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
			/* Clear SW Defineable Pin 0 to turn on the LED */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
			ctrl &= ~E1000_CTRL_SWDPIN0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
			ctrl |= E1000_CTRL_SWDPIO0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
		} else if (hw->media_type == e1000_media_type_copper) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
			ew32(LEDCTL, hw->ledctl_mode2);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
			return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
	ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
 * e1000_led_off - Turns off the software controllable LED
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
s32 e1000_led_off(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
	u32 ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
	e_dbg("e1000_led_off");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
	case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
	case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
	case e1000_82543:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
		/* Clear SW Defineable Pin 0 to turn off the LED */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
		ctrl &= ~E1000_CTRL_SWDPIN0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
		ctrl |= E1000_CTRL_SWDPIO0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
		if (hw->media_type == e1000_media_type_fiber) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
			/* Clear SW Defineable Pin 0 to turn off the LED */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
			ctrl &= ~E1000_CTRL_SWDPIN0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
			ctrl |= E1000_CTRL_SWDPIO0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
			/* Set SW Defineable Pin 0 to turn off the LED */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
			ctrl |= E1000_CTRL_SWDPIN0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
			ctrl |= E1000_CTRL_SWDPIO0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
		if (hw->media_type == e1000_media_type_fiber) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
			/* Set SW Defineable Pin 0 to turn off the LED */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
			ctrl |= E1000_CTRL_SWDPIN0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
			ctrl |= E1000_CTRL_SWDPIO0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
		} else if (hw->media_type == e1000_media_type_copper) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
			ew32(LEDCTL, hw->ledctl_mode1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
			return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
 * e1000_clear_hw_cntrs - Clears all hardware statistics counters.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
static void e1000_clear_hw_cntrs(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	volatile u32 temp;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	temp = er32(CRCERRS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	temp = er32(SYMERRS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	temp = er32(MPC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	temp = er32(SCC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	temp = er32(ECOL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	temp = er32(MCC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	temp = er32(LATECOL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	temp = er32(COLC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	temp = er32(DC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
	temp = er32(SEC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	temp = er32(RLEC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
	temp = er32(XONRXC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
	temp = er32(XONTXC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
	temp = er32(XOFFRXC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
	temp = er32(XOFFTXC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
	temp = er32(FCRUC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
	temp = er32(PRC64);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
	temp = er32(PRC127);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
	temp = er32(PRC255);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
	temp = er32(PRC511);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
	temp = er32(PRC1023);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	temp = er32(PRC1522);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
	temp = er32(GPRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
	temp = er32(BPRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	temp = er32(MPRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
	temp = er32(GPTC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	temp = er32(GORCL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	temp = er32(GORCH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
	temp = er32(GOTCL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	temp = er32(GOTCH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
	temp = er32(RNBC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
	temp = er32(RUC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
	temp = er32(RFC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
	temp = er32(ROC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
	temp = er32(RJC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
	temp = er32(TORL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
	temp = er32(TORH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
	temp = er32(TOTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
	temp = er32(TOTH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
	temp = er32(TPR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
	temp = er32(TPT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
	temp = er32(PTC64);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
	temp = er32(PTC127);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
	temp = er32(PTC255);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
	temp = er32(PTC511);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
	temp = er32(PTC1023);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
	temp = er32(PTC1522);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
	temp = er32(MPTC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
	temp = er32(BPTC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
	if (hw->mac_type < e1000_82543)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
	temp = er32(ALGNERRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
	temp = er32(RXERRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
	temp = er32(TNCRS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
	temp = er32(CEXTERR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
	temp = er32(TSCTC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
	temp = er32(TSCTFC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
	if (hw->mac_type <= e1000_82544)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	temp = er32(MGTPRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
	temp = er32(MGTPDC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
	temp = er32(MGTPTC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
 * e1000_reset_adaptive - Resets Adaptive IFS to its default state.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
 * Call this after e1000_init_hw. You may override the IFS defaults by setting
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
 * hw->ifs_params_forced to true. However, you must initialize hw->
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
 * current_ifs_val, ifs_min_val, ifs_max_val, ifs_step_size, and ifs_ratio
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
 * before calling this function.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
void e1000_reset_adaptive(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
	e_dbg("e1000_reset_adaptive");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	if (hw->adaptive_ifs) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
		if (!hw->ifs_params_forced) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
			hw->current_ifs_val = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
			hw->ifs_min_val = IFS_MIN;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
			hw->ifs_max_val = IFS_MAX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
			hw->ifs_step_size = IFS_STEP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
			hw->ifs_ratio = IFS_RATIO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
		hw->in_ifs_mode = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
		ew32(AIT, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
		e_dbg("Not in Adaptive IFS mode!\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
 * e1000_update_adaptive - update adaptive IFS
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
 * @tx_packets: Number of transmits since last callback
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
 * @total_collisions: Number of collisions since last callback
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
 * Called during the callback/watchdog routine to update IFS value based on
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
 * the ratio of transmits to collisions.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
void e1000_update_adaptive(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
	e_dbg("e1000_update_adaptive");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
	if (hw->adaptive_ifs) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
		if ((hw->collision_delta *hw->ifs_ratio) > hw->tx_packet_delta) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
			if (hw->tx_packet_delta > MIN_NUM_XMITS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
				hw->in_ifs_mode = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
				if (hw->current_ifs_val < hw->ifs_max_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
					if (hw->current_ifs_val == 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
						hw->current_ifs_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
						    hw->ifs_min_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
					else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
						hw->current_ifs_val +=
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
						    hw->ifs_step_size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
					ew32(AIT, hw->current_ifs_val);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
				}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
			if (hw->in_ifs_mode
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
			    && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
				hw->current_ifs_val = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
				hw->in_ifs_mode = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
				ew32(AIT, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
		e_dbg("Not in Adaptive IFS mode!\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
 * e1000_tbi_adjust_stats
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
 * @frame_len: The length of the frame in question
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
 * @mac_addr: The Ethernet destination address of the frame in question
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
 * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
			    u32 frame_len, u8 *mac_addr)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
	u64 carry_bit;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
	/* First adjust the frame length. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
	frame_len--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
	/* We need to adjust the statistics counters, since the hardware
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
	 * counters overcount this packet as a CRC error and undercount
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
	 * the packet as a good packet
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
	/* This packet should not be counted as a CRC error.    */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
	stats->crcerrs--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
	/* This packet does count as a Good Packet Received.    */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
	stats->gprc++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
	/* Adjust the Good Octets received counters             */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
	carry_bit = 0x80000000 & stats->gorcl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
	stats->gorcl += frame_len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
	/* If the high bit of Gorcl (the low 32 bits of the Good Octets
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
	 * Received Count) was one before the addition,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
	 * AND it is zero after, then we lost the carry out,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
	 * need to add one to Gorch (Good Octets Received Count High).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
	 * This could be simplified if all environments supported
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
	 * 64-bit integers.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
	if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
		stats->gorch++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
	/* Is this a broadcast or multicast?  Check broadcast first,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
	 * since the test for a multicast frame will test positive on
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
	 * a broadcast frame.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
	if ((mac_addr[0] == (u8) 0xff) && (mac_addr[1] == (u8) 0xff))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
		/* Broadcast packet */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
		stats->bprc++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
	else if (*mac_addr & 0x01)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
		/* Multicast packet */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
		stats->mprc++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
	if (frame_len == hw->max_frame_size) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
		/* In this case, the hardware has overcounted the number of
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
		 * oversize frames.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
		if (stats->roc > 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
			stats->roc--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
	/* Adjust the bin counters when the extra byte put the frame in the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
	 * wrong bin. Remember that the frame_len was adjusted above.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
	if (frame_len == 64) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
		stats->prc64++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
		stats->prc127--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
	} else if (frame_len == 127) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
		stats->prc127++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
		stats->prc255--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
	} else if (frame_len == 255) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
		stats->prc255++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
		stats->prc511--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
	} else if (frame_len == 511) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
		stats->prc511++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
		stats->prc1023--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
	} else if (frame_len == 1023) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
		stats->prc1023++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
		stats->prc1522--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
	} else if (frame_len == 1522) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
		stats->prc1522++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
 * e1000_get_bus_info
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
 * Gets the current PCI bus type, speed, and width of the hardware
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
void e1000_get_bus_info(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
	u32 status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
	case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
	case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
		hw->bus_type = e1000_bus_type_pci;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
		hw->bus_speed = e1000_bus_speed_unknown;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
		hw->bus_width = e1000_bus_width_unknown;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
		status = er32(STATUS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
		hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
		    e1000_bus_type_pcix : e1000_bus_type_pci;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
		if (hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
			hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
			    e1000_bus_speed_66 : e1000_bus_speed_120;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
		} else if (hw->bus_type == e1000_bus_type_pci) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
			hw->bus_speed = (status & E1000_STATUS_PCI66) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
			    e1000_bus_speed_66 : e1000_bus_speed_33;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
			switch (status & E1000_STATUS_PCIX_SPEED) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
			case E1000_STATUS_PCIX_SPEED_66:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
				hw->bus_speed = e1000_bus_speed_66;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
			case E1000_STATUS_PCIX_SPEED_100:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
				hw->bus_speed = e1000_bus_speed_100;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
			case E1000_STATUS_PCIX_SPEED_133:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
				hw->bus_speed = e1000_bus_speed_133;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
			default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
				hw->bus_speed = e1000_bus_speed_reserved;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
		hw->bus_width = (status & E1000_STATUS_BUS64) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
		    e1000_bus_width_64 : e1000_bus_width_32;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
 * e1000_write_reg_io
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
 * @offset: offset to write to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
 * @value: value to write
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
 * Writes a value to one of the devices registers using port I/O (as opposed to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
 * memory mapped I/O). Only 82544 and newer devices support port I/O.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
	unsigned long io_addr = hw->io_base;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
	unsigned long io_data = hw->io_base + 4;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
	e1000_io_write(hw, io_addr, offset);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
	e1000_io_write(hw, io_data, value);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
 * e1000_get_cable_length - Estimates the cable length.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
 * @min_length: The estimated minimum length
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
 * @max_length: The estimated maximum length
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
 * returns: - E1000_ERR_XXX
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
 *            E1000_SUCCESS
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
 * This function always returns a ranged length (minimum & maximum).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
 * So for M88 phy's, this function interprets the one value returned from the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
 * register to the minimum and maximum range.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
 * For IGP phy's, the function calculates the range by the AGC registers.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
				  u16 *max_length)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
	u16 agc_value = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
	u16 i, phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
	u16 cable_length;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
	e_dbg("e1000_get_cable_length");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
	*min_length = *max_length = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
	/* Use old method for Phy older than IGP */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
	if (hw->phy_type == e1000_phy_m88) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
					     &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
		cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
		    M88E1000_PSSR_CABLE_LENGTH_SHIFT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
		/* Convert the enum value to ranged values */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
		switch (cable_length) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
		case e1000_cable_length_50:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
			*min_length = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
			*max_length = e1000_igp_cable_length_50;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
		case e1000_cable_length_50_80:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
			*min_length = e1000_igp_cable_length_50;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
			*max_length = e1000_igp_cable_length_80;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
		case e1000_cable_length_80_110:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
			*min_length = e1000_igp_cable_length_80;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
			*max_length = e1000_igp_cable_length_110;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
		case e1000_cable_length_110_140:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
			*min_length = e1000_igp_cable_length_110;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
			*max_length = e1000_igp_cable_length_140;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
		case e1000_cable_length_140:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
			*min_length = e1000_igp_cable_length_140;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
			*max_length = e1000_igp_cable_length_170;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
		default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
			return -E1000_ERR_PHY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
	} else if (hw->phy_type == e1000_phy_igp) {	/* For IGP PHY */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
		u16 cur_agc_value;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
		u16 min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
		static const u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
		       IGP01E1000_PHY_AGC_A,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
		       IGP01E1000_PHY_AGC_B,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
		       IGP01E1000_PHY_AGC_C,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
		       IGP01E1000_PHY_AGC_D
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
		};
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
		/* Read the AGC registers for all channels */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
		for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
			    e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
			cur_agc_value = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
			/* Value bound check. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
			if ((cur_agc_value >=
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
			     IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
			    || (cur_agc_value == 0))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
				return -E1000_ERR_PHY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
			agc_value += cur_agc_value;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
			/* Update minimal AGC value. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
			if (min_agc_value > cur_agc_value)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
				min_agc_value = cur_agc_value;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
		/* Remove the minimal AGC result for length < 50m */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
		if (agc_value <
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
		    IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
			agc_value -= min_agc_value;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
			/* Get the average length of the remaining 3 channels */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
			agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
			/* Get the average length of all the 4 channels. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
			agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
		/* Set the range of the calculated length. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
		*min_length = ((e1000_igp_cable_length_table[agc_value] -
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
				IGP01E1000_AGC_RANGE) > 0) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
		    (e1000_igp_cable_length_table[agc_value] -
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
		     IGP01E1000_AGC_RANGE) : 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
		*max_length = e1000_igp_cable_length_table[agc_value] +
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
		    IGP01E1000_AGC_RANGE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
 * e1000_check_polarity - Check the cable polarity
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
 * @polarity: output parameter : 0 - Polarity is not reversed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
 *                               1 - Polarity is reversed.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
 * returns: - E1000_ERR_XXX
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
 *            E1000_SUCCESS
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
 * For phy's older than IGP, this function simply reads the polarity bit in the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
 * Phy Status register.  For IGP phy's, this bit is valid only if link speed is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
 * 10 Mbps.  If the link speed is 100 Mbps there is no polarity so this bit will
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
 * return 0.  If the link speed is 1000 Mbps the polarity status is in the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
 * IGP01E1000_PHY_PCS_INIT_REG.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
static s32 e1000_check_polarity(struct e1000_hw *hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
				e1000_rev_polarity *polarity)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
	e_dbg("e1000_check_polarity");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
	if (hw->phy_type == e1000_phy_m88) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
		/* return the Polarity bit in the Status register. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
					     &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
		*polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
			     M88E1000_PSSR_REV_POLARITY_SHIFT) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
		    e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
	} else if (hw->phy_type == e1000_phy_igp) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
		/* Read the Status register to check the speed */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
					     &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
		/* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
		 * find the polarity status */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
		if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
		    IGP01E1000_PSSR_SPEED_1000MBPS) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
			/* Read the GIG initialization PCS register (0x00B4) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
					       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
			/* Check the polarity bits */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
			*polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
			    e1000_rev_polarity_reversed :
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
			    e1000_rev_polarity_normal;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
			/* For 10 Mbps, read the polarity bit in the status register. (for
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
			 * 100 Mbps this bit is always 0) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
			*polarity =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
			    (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
			    e1000_rev_polarity_reversed :
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
			    e1000_rev_polarity_normal;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
 * e1000_check_downshift - Check if Downshift occurred
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
 * @downshift: output parameter : 0 - No Downshift occurred.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
 *                                1 - Downshift occurred.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
 * returns: - E1000_ERR_XXX
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
 *            E1000_SUCCESS
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
 * For phy's older than IGP, this function reads the Downshift bit in the Phy
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
 * Specific Status register.  For IGP phy's, it reads the Downgrade bit in the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
 * Link Health register.  In IGP this bit is latched high, so the driver must
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
 * read it immediately after link is established.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
static s32 e1000_check_downshift(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
	e_dbg("e1000_check_downshift");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
	if (hw->phy_type == e1000_phy_igp) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
					     &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
		hw->speed_downgraded =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
		    (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
	} else if (hw->phy_type == e1000_phy_m88) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
					     &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
		hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
		    M88E1000_PSSR_DOWNSHIFT_SHIFT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
 * e1000_config_dsp_after_link_change
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
 * @link_up: was link up at the time this was called
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
 *            E1000_SUCCESS at any other case.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
 * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
 * gigabit link is achieved to improve link quality.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw, bool link_up)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
	u16 phy_data, phy_saved_data, speed, duplex, i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
	static const u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	       IGP01E1000_PHY_AGC_PARAM_A,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
	       IGP01E1000_PHY_AGC_PARAM_B,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
	       IGP01E1000_PHY_AGC_PARAM_C,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
	       IGP01E1000_PHY_AGC_PARAM_D
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
	};
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
	u16 min_length, max_length;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
	e_dbg("e1000_config_dsp_after_link_change");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
	if (hw->phy_type != e1000_phy_igp)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
	if (link_up) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
		ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
			e_dbg("Error getting link speed and duplex\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
		if (speed == SPEED_1000) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
			    e1000_get_cable_length(hw, &min_length,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
						   &max_length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
			if ((hw->dsp_config_state == e1000_dsp_config_enabled)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
			    && min_length >= e1000_igp_cable_length_50) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
				for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
					ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
					    e1000_read_phy_reg(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
							       dsp_reg_array[i],
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
							       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
					if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
						return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
					phy_data &=
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
					    ~IGP01E1000_PHY_EDAC_MU_INDEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
					ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
					    e1000_write_phy_reg(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
								dsp_reg_array
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
								[i], phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
					if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
						return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
				}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
				hw->dsp_config_state =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
				    e1000_dsp_config_activated;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
			if ((hw->ffe_config_state == e1000_ffe_config_enabled)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
			    && (min_length < e1000_igp_cable_length_50)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
				u16 ffe_idle_err_timeout =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
				    FFE_IDLE_ERR_COUNT_TIMEOUT_20;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
				u32 idle_errs = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
				/* clear previous idle error counts */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
				ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
				    e1000_read_phy_reg(hw, PHY_1000T_STATUS,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
						       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
				if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
					return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
				for (i = 0; i < ffe_idle_err_timeout; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
					udelay(1000);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
					ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
					    e1000_read_phy_reg(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
							       PHY_1000T_STATUS,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
							       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
					if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
						return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
					idle_errs +=
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
					    (phy_data &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
					     SR_1000T_IDLE_ERROR_CNT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
					if (idle_errs >
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
					    SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
					{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
						hw->ffe_config_state =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
						    e1000_ffe_config_active;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
						ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
						    e1000_write_phy_reg(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
									IGP01E1000_PHY_DSP_FFE,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
									IGP01E1000_PHY_DSP_FFE_CM_CP);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
						if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
							return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
						break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
					}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
					if (idle_errs)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
						ffe_idle_err_timeout =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
						    FFE_IDLE_ERR_COUNT_TIMEOUT_100;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
				}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
		if (hw->dsp_config_state == e1000_dsp_config_activated) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
			/* Save off the current value of register 0x2F5B to be restored at
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
			 * the end of the routines. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
			    e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
			/* Disable the PHY transmitter */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
			ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
			mdelay(20);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
			ret_val = e1000_write_phy_reg(hw, 0x0000,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
						      IGP01E1000_IEEE_FORCE_GIGA);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
			for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
				ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
				    e1000_read_phy_reg(hw, dsp_reg_array[i],
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
						       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
				if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
					return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
				phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
				phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
				ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
				    e1000_write_phy_reg(hw, dsp_reg_array[i],
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
							phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
				if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
					return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
			ret_val = e1000_write_phy_reg(hw, 0x0000,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
						      IGP01E1000_IEEE_RESTART_AUTONEG);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
			mdelay(20);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
			/* Now enable the transmitter */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
			    e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
			hw->dsp_config_state = e1000_dsp_config_enabled;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
		if (hw->ffe_config_state == e1000_ffe_config_active) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
			/* Save off the current value of register 0x2F5B to be restored at
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
			 * the end of the routines. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
			    e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
			/* Disable the PHY transmitter */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
			ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
			mdelay(20);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
			ret_val = e1000_write_phy_reg(hw, 0x0000,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
						      IGP01E1000_IEEE_FORCE_GIGA);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
						IGP01E1000_PHY_DSP_FFE_DEFAULT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
			ret_val = e1000_write_phy_reg(hw, 0x0000,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
						      IGP01E1000_IEEE_RESTART_AUTONEG);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
			mdelay(20);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
			/* Now enable the transmitter */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
			    e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
			hw->ffe_config_state = e1000_ffe_config_enabled;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
 * e1000_set_phy_mode - Set PHY to class A mode
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
 * Assumes the following operations will follow to enable the new class mode.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
 *  1. Do a PHY soft reset
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
 *  2. Restart auto-negotiation or force link.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
static s32 e1000_set_phy_mode(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
	u16 eeprom_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
	e_dbg("e1000_set_phy_mode");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
	if ((hw->mac_type == e1000_82545_rev_3) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
	    (hw->media_type == e1000_media_type_copper)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
		    e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
				      &eeprom_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
		if (ret_val) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
		if ((eeprom_data != EEPROM_RESERVED_WORD) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
		    (eeprom_data & EEPROM_PHY_CLASS_A)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
			    e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
						0x000B);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
			    e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
						0x8104);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
			hw->phy_reset_disable = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
 * e1000_set_d3_lplu_state - set d3 link power state
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
 * @active: true to enable lplu false to disable lplu.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
 * This function sets the lplu state according to the active flag.  When
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
 * activating lplu this function also disables smart speed and vise versa.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
 * lplu will not be activated unless the device autonegotiation advertisement
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
 * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
 *            E1000_SUCCESS at any other case.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
	e_dbg("e1000_set_d3_lplu_state");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
	if (hw->phy_type != e1000_phy_igp)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
	/* During driver activity LPLU should not be used or it will attain link
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
	 * from the lowest speeds starting from 10Mbps. The capability is used for
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
	 * Dx transitions and states */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
	if (hw->mac_type == e1000_82541_rev_2
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
	    || hw->mac_type == e1000_82547_rev_2) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
		    e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
	if (!active) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
		if (hw->mac_type == e1000_82541_rev_2 ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
		    hw->mac_type == e1000_82547_rev_2) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
			phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
			    e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
						phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
		 * Dx states where the power conservation is most important.  During
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
		 * driver activity we should enable SmartSpeed, so performance is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
		 * maintained. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
		if (hw->smart_speed == e1000_smart_speed_on) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
					       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
			phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
						phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
		} else if (hw->smart_speed == e1000_smart_speed_off) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
					       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
						phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
	} else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
		   || (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
		   || (hw->autoneg_advertised ==
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
		       AUTONEG_ADVERTISE_10_100_ALL)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
		if (hw->mac_type == e1000_82541_rev_2 ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
		    hw->mac_type == e1000_82547_rev_2) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
			phy_data |= IGP01E1000_GMII_FLEX_SPD;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
			ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
			    e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
						phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
			if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
				return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
		/* When LPLU is enabled we should disable SmartSpeed */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
		    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
				       &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
		phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
		ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
		    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
					phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
 * e1000_set_vco_speed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
 * Change VCO speed register to improve Bit Error Rate performance of SERDES.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5635
static s32 e1000_set_vco_speed(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5636
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5637
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5638
	u16 default_page = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5639
	u16 phy_data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5640
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5641
	e_dbg("e1000_set_vco_speed");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5642
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5643
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5644
	case e1000_82545_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5645
	case e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5646
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5647
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5648
		return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5649
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5650
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5651
	/* Set PHY register 30, page 5, bit 8 to 0 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5652
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5653
	ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5654
	    e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5655
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5656
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5657
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5658
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5659
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5660
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5661
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5662
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5663
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5664
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5665
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5666
	phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5667
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5668
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5669
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5670
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5671
	/* Set PHY register 30, page 4, bit 11 to 1 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5672
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5673
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5674
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5675
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5676
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5677
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5678
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5679
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5680
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5681
	phy_data |= M88E1000_PHY_VCO_REG_BIT11;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5682
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5683
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5684
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5685
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5686
	ret_val =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5687
	    e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5688
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5689
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5690
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5691
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5692
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5693
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5694
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5695
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5696
 * e1000_enable_mng_pass_thru - check for bmc pass through
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5697
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5698
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5699
 * Verifies the hardware needs to allow ARPs to be processed by the host
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5700
 * returns: - true/false
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5701
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5702
u32 e1000_enable_mng_pass_thru(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5703
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5704
	u32 manc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5705
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5706
	if (hw->asf_firmware_present) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5707
		manc = er32(MANC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5708
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5709
		if (!(manc & E1000_MANC_RCV_TCO_EN) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5710
		    !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5711
			return false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5712
		if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5713
			return true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5714
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5715
	return false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5716
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5717
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5718
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5719
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5720
	s32 ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5721
	u16 mii_status_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5722
	u16 i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5723
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5724
	/* Polarity reversal workaround for forced 10F/10H links. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5725
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5726
	/* Disable the transmitter on the PHY */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5727
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5728
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5729
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5730
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5731
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5732
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5733
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5734
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5735
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5736
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5737
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5738
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5739
	/* This loop will early-out if the NO link condition has been met. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5740
	for (i = PHY_FORCE_TIME; i > 0; i--) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5741
		/* Read the MII Status Register and wait for Link Status bit
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5742
		 * to be clear.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5743
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5744
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5745
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5746
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5747
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5748
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5749
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5750
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5751
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5752
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5753
		if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5754
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5755
		mdelay(100);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5756
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5757
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5758
	/* Recommended delay time after link has been lost */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5759
	mdelay(1000);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5760
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5761
	/* Now we will re-enable th transmitter on the PHY */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5762
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5763
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5764
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5765
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5766
	mdelay(50);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5767
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5768
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5769
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5770
	mdelay(50);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5771
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5772
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5773
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5774
	mdelay(50);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5775
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5776
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5777
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5778
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5779
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5780
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5781
		return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5782
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5783
	/* This loop will early-out if the link condition has been met. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5784
	for (i = PHY_FORCE_TIME; i > 0; i--) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5785
		/* Read the MII Status Register and wait for Link Status bit
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5786
		 * to be set.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5787
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5788
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5789
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5790
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5791
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5792
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5793
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5794
		if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5795
			return ret_val;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5796
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5797
		if (mii_status_reg & MII_SR_LINK_STATUS)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5798
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5799
		mdelay(100);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5800
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5801
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5802
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5803
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5804
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5805
 * e1000_get_auto_rd_done
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5806
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5807
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5808
 * Check for EEPROM Auto Read bit done.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5809
 * returns: - E1000_ERR_RESET if fail to reset MAC
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5810
 *            E1000_SUCCESS at any other case.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5811
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5812
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5813
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5814
	e_dbg("e1000_get_auto_rd_done");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5815
	msleep(5);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5816
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5817
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5818
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5819
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5820
 * e1000_get_phy_cfg_done
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5821
 * @hw: Struct containing variables accessed by shared code
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5822
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5823
 * Checks if the PHY configuration is done
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5824
 * returns: - E1000_ERR_RESET if fail to reset MAC
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5825
 *            E1000_SUCCESS at any other case.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5826
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5827
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5828
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5829
	e_dbg("e1000_get_phy_cfg_done");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5830
	mdelay(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5831
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5832
}