devices/e1000/e1000_hw-2.6.32-orig.c
author Gavin Lambert <gavinl@compacsort.com>
Tue, 14 Apr 2015 09:33:24 -0400
changeset 2618 3affe9cd0b66
parent 2171 4eff8c9cfbbc
permissions -rw-r--r--
Ignore NXIO error otherwise this causes spam if network is empty or refclk not
selected yet, and syncing refclk time to master.
2171
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
/* e1000_hw.c
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
 * Shared functions for accessing and configuring the MAC
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include "e1000_hw.h"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
static s32 e1000_check_downshift(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static s32 e1000_check_polarity(struct e1000_hw *hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
				e1000_rev_polarity *polarity);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
static void e1000_clear_vfta(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
					      bool link_up);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
static s32 e1000_detect_gig_phy(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
				  u16 *max_length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
static s32 e1000_id_led_init(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
static void e1000_init_rx_addrs(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
				  struct e1000_phy_info *phy_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
				  struct e1000_phy_info *phy_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
static s32 e1000_wait_autoneg(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
static s32 e1000_set_phy_type(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
static void e1000_phy_init_script(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
static s32 e1000_setup_copper_link(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
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);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
				  u16 words, u16 *data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
					u16 words, u16 *data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
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);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
				  u16 phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
				 u16 *phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
static s32 e1000_acquire_eeprom(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
static void e1000_release_eeprom(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
static void e1000_standby_eeprom(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
static s32 e1000_set_vco_speed(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
static s32 e1000_set_phy_mode(struct e1000_hw *hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
				u16 *data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
				 u16 *data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
/* IGP cable length table */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
static const
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
u16 e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
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,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
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,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
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,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
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,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
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,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
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,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	    100,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	    110, 110,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	    120, 120
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static DEFINE_SPINLOCK(e1000_eeprom_lock);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
 * e1000_set_phy_type - Set the phy type member in the hw struct.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static s32 e1000_set_phy_type(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	DEBUGFUNC("e1000_set_phy_type");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	if (hw->mac_type == e1000_undefined)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
		return -E1000_ERR_PHY_TYPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	switch (hw->phy_id) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	case M88E1000_E_PHY_ID:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	case M88E1000_I_PHY_ID:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	case M88E1011_I_PHY_ID:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	case M88E1111_I_PHY_ID:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
		hw->phy_type = e1000_phy_m88;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	case IGP01E1000_I_PHY_ID:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
		if (hw->mac_type == e1000_82541 ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
		    hw->mac_type == e1000_82541_rev_2 ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
		    hw->mac_type == e1000_82547 ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
		    hw->mac_type == e1000_82547_rev_2) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
			hw->phy_type = e1000_phy_igp;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
		/* Should never have loaded on this device */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
		hw->phy_type = e1000_phy_undefined;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
		return -E1000_ERR_PHY_TYPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
 * e1000_phy_init_script - IGP phy init script - initializes the GbE PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static void e1000_phy_init_script(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
	u32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
	u16 phy_saved_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
	DEBUGFUNC("e1000_phy_init_script");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	if (hw->phy_init_script) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
		msleep(20);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
		/* Save off the current value of register 0x2F5B to be restored at
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
		 * the end of this routine. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
		ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
		/* Disabled the PHY transmitter */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
		e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
		msleep(20);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
		e1000_write_phy_reg(hw, 0x0000, 0x0140);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
		msleep(5);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
		case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
		case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
			e1000_write_phy_reg(hw, 0x1F95, 0x0001);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
			e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
			e1000_write_phy_reg(hw, 0x1F79, 0x0018);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
			e1000_write_phy_reg(hw, 0x1F30, 0x1600);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
			e1000_write_phy_reg(hw, 0x1F31, 0x0014);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
			e1000_write_phy_reg(hw, 0x1F32, 0x161C);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
			e1000_write_phy_reg(hw, 0x1F94, 0x0003);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
			e1000_write_phy_reg(hw, 0x1F96, 0x003F);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
			e1000_write_phy_reg(hw, 0x2010, 0x0008);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
		case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
		case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
			e1000_write_phy_reg(hw, 0x1F73, 0x0099);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
		e1000_write_phy_reg(hw, 0x0000, 0x3300);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
		msleep(20);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
		/* Now enable the transmitter */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
		e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		if (hw->mac_type == e1000_82547) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
			u16 fused, fine, coarse;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
			/* Move to analog registers page */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
			e1000_read_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
					   IGP01E1000_ANALOG_SPARE_FUSE_STATUS,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
					   &fused);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
			if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
				e1000_read_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
						   IGP01E1000_ANALOG_FUSE_STATUS,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
						   &fused);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
				fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
				coarse =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
				    fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
				if (coarse >
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
				    IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
					coarse -=
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
					    IGP01E1000_ANALOG_FUSE_COARSE_10;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
					fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
				} else if (coarse ==
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
					   IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
					fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
				fused =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
				    (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
				    (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
				    (coarse &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
				     IGP01E1000_ANALOG_FUSE_COARSE_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
				e1000_write_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
						    IGP01E1000_ANALOG_FUSE_CONTROL,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
						    fused);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
				e1000_write_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
						    IGP01E1000_ANALOG_FUSE_BYPASS,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
						    IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
 * e1000_set_mac_type - Set the mac type member in the hw struct.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
s32 e1000_set_mac_type(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	DEBUGFUNC("e1000_set_mac_type");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	switch (hw->device_id) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	case E1000_DEV_ID_82542:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
		switch (hw->revision_id) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
		case E1000_82542_2_0_REV_ID:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
			hw->mac_type = e1000_82542_rev2_0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
		case E1000_82542_2_1_REV_ID:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
			hw->mac_type = e1000_82542_rev2_1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
			/* Invalid 82542 revision ID */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
			return -E1000_ERR_MAC_TYPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	case E1000_DEV_ID_82543GC_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	case E1000_DEV_ID_82543GC_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
		hw->mac_type = e1000_82543;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	case E1000_DEV_ID_82544EI_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	case E1000_DEV_ID_82544EI_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	case E1000_DEV_ID_82544GC_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	case E1000_DEV_ID_82544GC_LOM:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
		hw->mac_type = e1000_82544;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	case E1000_DEV_ID_82540EM:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	case E1000_DEV_ID_82540EM_LOM:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	case E1000_DEV_ID_82540EP:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	case E1000_DEV_ID_82540EP_LOM:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	case E1000_DEV_ID_82540EP_LP:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		hw->mac_type = e1000_82540;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	case E1000_DEV_ID_82545EM_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	case E1000_DEV_ID_82545EM_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
		hw->mac_type = e1000_82545;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	case E1000_DEV_ID_82545GM_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	case E1000_DEV_ID_82545GM_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	case E1000_DEV_ID_82545GM_SERDES:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
		hw->mac_type = e1000_82545_rev_3;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	case E1000_DEV_ID_82546EB_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	case E1000_DEV_ID_82546EB_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
		hw->mac_type = e1000_82546;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	case E1000_DEV_ID_82546GB_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	case E1000_DEV_ID_82546GB_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	case E1000_DEV_ID_82546GB_SERDES:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	case E1000_DEV_ID_82546GB_PCIE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	case E1000_DEV_ID_82546GB_QUAD_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
		hw->mac_type = e1000_82546_rev_3;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	case E1000_DEV_ID_82541EI:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	case E1000_DEV_ID_82541EI_MOBILE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	case E1000_DEV_ID_82541ER_LOM:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		hw->mac_type = e1000_82541;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
	case E1000_DEV_ID_82541ER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	case E1000_DEV_ID_82541GI:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	case E1000_DEV_ID_82541GI_LF:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	case E1000_DEV_ID_82541GI_MOBILE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		hw->mac_type = e1000_82541_rev_2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	case E1000_DEV_ID_82547EI:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	case E1000_DEV_ID_82547EI_MOBILE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		hw->mac_type = e1000_82547;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	case E1000_DEV_ID_82547GI:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		hw->mac_type = e1000_82547_rev_2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
		/* Should never have loaded on this device */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
		return -E1000_ERR_MAC_TYPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
	case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		hw->asf_firmware_present = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	/* The 82543 chip does not count tx_carrier_errors properly in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	 * FD mode
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	if (hw->mac_type == e1000_82543)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		hw->bad_tx_carr_stats_fd = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	if (hw->mac_type > e1000_82544)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		hw->has_smbus = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
 * e1000_set_media_type - Set media type and TBI compatibility.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
void e1000_set_media_type(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	u32 status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
	DEBUGFUNC("e1000_set_media_type");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
	if (hw->mac_type != e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
		/* tbi_compatibility is only valid on 82543 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
		hw->tbi_compatibility_en = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	switch (hw->device_id) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	case E1000_DEV_ID_82545GM_SERDES:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	case E1000_DEV_ID_82546GB_SERDES:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
		hw->media_type = e1000_media_type_internal_serdes;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
		case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
		case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
			hw->media_type = e1000_media_type_fiber;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
			status = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
			if (status & E1000_STATUS_TBIMODE) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
				hw->media_type = e1000_media_type_fiber;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
				/* tbi_compatibility not valid on fiber */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
				hw->tbi_compatibility_en = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
			} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
				hw->media_type = e1000_media_type_copper;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
 * e1000_reset_hw: reset the hardware completely
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
 * Reset the transmit and receive units; mask and clear all interrupts.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
s32 e1000_reset_hw(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	u32 ctrl_ext;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	u32 icr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	u32 manc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	u32 led_ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
	DEBUGFUNC("e1000_reset_hw");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	/* For 82542 (rev 2.0), disable MWI before issuing a device reset */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	if (hw->mac_type == e1000_82542_rev2_0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
		DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
		e1000_pci_clear_mwi(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	/* Clear interrupt mask to stop board from generating interrupts */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	DEBUGOUT("Masking off all interrupts\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	ew32(IMC, 0xffffffff);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	/* Disable the Transmit and Receive units.  Then delay to allow
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	 * any pending transactions to complete before we hit the MAC with
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	 * the global reset.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	ew32(RCTL, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	ew32(TCTL, E1000_TCTL_PSP);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	/* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	hw->tbi_compatibility_on = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
	/* Delay to allow any outstanding PCI transactions to complete before
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	 * resetting the device
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	/* Must reset the PHY before resetting the MAC */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
		ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		msleep(5);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
	/* Issue a global reset to the MAC.  This will reset the chip's
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	 * transmit, receive, DMA, and link units.  It will not effect
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	 * the current PCI configuration.  The global reset bit is self-
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	 * clearing, and should clear within a microsecond.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	DEBUGOUT("Issuing a global reset to MAC\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	case e1000_82540:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	case e1000_82545:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	case e1000_82546:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
		/* These controllers can't ack the 64-bit write when issuing the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		 * reset, so use IO-mapping as a workaround to issue the reset */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
		E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		/* Reset is performed on a shadow of the control register */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		ew32(CTRL_DUP, (ctrl | E1000_CTRL_RST));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		ew32(CTRL, (ctrl | E1000_CTRL_RST));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	/* After MAC reset, force reload of EEPROM to restore power-on settings to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	 * device.  Later controllers reload the EEPROM automatically, so just wait
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	 * for reload to complete.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
	case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	case e1000_82543:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		/* Wait for reset to complete */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
		udelay(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		ctrl_ext = er32(CTRL_EXT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
		ctrl_ext |= E1000_CTRL_EXT_EE_RST;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		ew32(CTRL_EXT, ctrl_ext);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
		/* Wait for EEPROM reload */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
		msleep(2);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
		/* Wait for EEPROM reload */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		msleep(20);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		/* Auto read done will delay 5ms or poll based on mac type */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		ret_val = e1000_get_auto_rd_done(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	/* Disable HW ARPs on ASF enabled adapters */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	if (hw->mac_type >= e1000_82540) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
		manc = er32(MANC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		manc &= ~(E1000_MANC_ARP_EN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		ew32(MANC, manc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
		e1000_phy_init_script(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		/* Configure activity LED after PHY reset */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		led_ctrl = er32(LEDCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
		ew32(LEDCTL, led_ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	/* Clear interrupt mask to stop board from generating interrupts */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	DEBUGOUT("Masking off all interrupts\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	ew32(IMC, 0xffffffff);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	/* Clear any pending interrupt events. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	icr = er32(ICR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	/* If MWI was previously enabled, reenable it. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	if (hw->mac_type == e1000_82542_rev2_0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
			e1000_pci_set_mwi(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
 * e1000_init_hw: Performs basic configuration of the adapter.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
 * Assumes that the controller has previously been reset and is in a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
 * post-reset uninitialized state. Initializes the receive address registers,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
 * multicast table, and VLAN filter table. Calls routines to setup link
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
 * configuration and flow control settings. Clears all on-chip counters. Leaves
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
 * the transmit and receive units disabled and uninitialized.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
s32 e1000_init_hw(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	u32 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	u32 mta_size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	u32 ctrl_ext;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	DEBUGFUNC("e1000_init_hw");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	/* Initialize Identification LED */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	ret_val = e1000_id_led_init(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		DEBUGOUT("Error Initializing Identification LED\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	/* Set the media type and TBI compatibility */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	e1000_set_media_type(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	/* Disabling VLAN filtering. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	DEBUGOUT("Initializing the IEEE VLAN\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	if (hw->mac_type < e1000_82545_rev_3)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
		ew32(VET, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	e1000_clear_vfta(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
	if (hw->mac_type == e1000_82542_rev2_0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
		DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
		e1000_pci_clear_mwi(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		ew32(RCTL, E1000_RCTL_RST);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
		msleep(5);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	/* Setup the receive address. This involves initializing all of the Receive
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	 * Address Registers (RARs 0 - 15).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	e1000_init_rx_addrs(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	if (hw->mac_type == e1000_82542_rev2_0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		ew32(RCTL, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		msleep(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
			e1000_pci_set_mwi(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	/* Zero out the Multicast HASH table */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	DEBUGOUT("Zeroing the MTA\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	mta_size = E1000_MC_TBL_SIZE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	for (i = 0; i < mta_size; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		/* use write flush to prevent Memory Write Block (MWB) from
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		 * occurring when accessing our register space */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	/* Set the PCI priority bit correctly in the CTRL register.  This
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	 * determines if the adapter gives priority to receives, or if it
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	 * gives equal priority to transmits and receives.  Valid only on
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	 * 82542 and 82543 silicon.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		ew32(CTRL, ctrl | E1000_CTRL_PRIOR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
		/* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
		if (hw->bus_type == e1000_bus_type_pcix
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
		    && e1000_pcix_get_mmrbc(hw) > 2048)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
			e1000_pcix_set_mmrbc(hw, 2048);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	/* Call a subroutine to configure the link and setup flow control. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	ret_val = e1000_setup_link(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	/* Set the transmit descriptor write-back policy */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	if (hw->mac_type > e1000_82544) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		ctrl = er32(TXDCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		ctrl =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		    (ctrl & ~E1000_TXDCTL_WTHRESH) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		    E1000_TXDCTL_FULL_TX_DESC_WB;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		ew32(TXDCTL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	/* Clear all of the statistics registers (clear on read).  It is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	 * important that we do this after we have tried to establish link
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	 * because the symbol error count will increment wildly if there
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	 * is no link.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	e1000_clear_hw_cntrs(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	    hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		ctrl_ext = er32(CTRL_EXT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		/* Relaxed ordering must be disabled to avoid a parity
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		 * error crash in a PCI slot. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		ew32(CTRL_EXT, ctrl_ext);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
 * e1000_adjust_serdes_amplitude - Adjust SERDES output amplitude based on EEPROM setting.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
 * @hw: Struct containing variables accessed by shared code.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	u16 eeprom_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	DEBUGFUNC("e1000_adjust_serdes_amplitude");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	if (hw->media_type != e1000_media_type_internal_serdes)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
	case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	                            &eeprom_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	if (eeprom_data != EEPROM_RESERVED_WORD) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
		/* Adjust SERDES output amplitude only. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
		eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
		    e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
 * e1000_setup_link - Configures flow control and link settings.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
 * Determines which flow control settings to use. Calls the appropriate media-
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
 * specific link configuration function. Configures the flow control settings.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
 * Assuming the adapter has a valid link partner, a valid link should be
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
 * established. Assumes the hardware has previously been reset and the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
 * transmitter and receiver are not enabled.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
s32 e1000_setup_link(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	u32 ctrl_ext;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	u16 eeprom_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	DEBUGFUNC("e1000_setup_link");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	/* Read and store word 0x0F of the EEPROM. This word contains bits
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	 * that determine the hardware's default PAUSE (flow control) mode,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	 * a bit that determines whether the HW defaults to enabling or
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	 * disabling auto-negotiation, and the direction of the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	 * SW defined pins. If there is no SW over-ride of the flow
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	 * control setting, then the variable hw->fc will
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	 * be initialized based on a value in the EEPROM.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	if (hw->fc == E1000_FC_DEFAULT) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
		ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
					    1, &eeprom_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
			DEBUGOUT("EEPROM Read Error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
			return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
		if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
			hw->fc = E1000_FC_NONE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
		else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
			 EEPROM_WORD0F_ASM_DIR)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
			hw->fc = E1000_FC_TX_PAUSE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
			hw->fc = E1000_FC_FULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	/* We want to save off the original Flow Control configuration just
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
	 * in case we get disconnected and then reconnected into a different
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	 * hub or switch with different Flow Control capabilities.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	if (hw->mac_type == e1000_82542_rev2_0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
		hw->fc &= (~E1000_FC_TX_PAUSE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		hw->fc &= (~E1000_FC_RX_PAUSE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	hw->original_fc = hw->fc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	/* Take the 4 bits from EEPROM word 0x0F that determine the initial
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	 * polarity value for the SW controlled pins, and setup the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	 * Extended Device Control reg with that info.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	 * This is needed because one of the SW controlled pins is used for
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	 * signal detection.  So this should be done before e1000_setup_pcs_link()
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	 * or e1000_phy_setup() is called.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	if (hw->mac_type == e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
		ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
					    1, &eeprom_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
			DEBUGOUT("EEPROM Read Error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
			return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
			    SWDPIO__EXT_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		ew32(CTRL_EXT, ctrl_ext);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	/* Call the necessary subroutine to configure the link. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	ret_val = (hw->media_type == e1000_media_type_copper) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	    e1000_setup_copper_link(hw) : e1000_setup_fiber_serdes_link(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	/* Initialize the flow control address, type, and PAUSE timer
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	 * registers to their default values.  This is done even if flow
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	 * control is disabled, because it does not hurt anything to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	 * initialize these registers.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	    ("Initializing the Flow Control address, type and timer regs\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	ew32(FCT, FLOW_CONTROL_TYPE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	ew32(FCTTV, hw->fc_pause_time);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	/* Set the flow control receive threshold registers.  Normally,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	 * these registers will be set to a default threshold that may be
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	 * adjusted later by the driver's runtime code.  However, if the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	 * ability to transmit pause frames in not enabled, then these
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	 * registers will be set to 0.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	if (!(hw->fc & E1000_FC_TX_PAUSE)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		ew32(FCRTL, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
		ew32(FCRTH, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
		/* We need to set up the Receive Threshold high and low water marks
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
		 * as well as (optionally) enabling the transmission of XON frames.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
		if (hw->fc_send_xon) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
			ew32(FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
			ew32(FCRTH, hw->fc_high_water);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
			ew32(FCRTL, hw->fc_low_water);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
			ew32(FCRTH, hw->fc_high_water);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
 * e1000_setup_fiber_serdes_link - prepare fiber or serdes link
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
 * Manipulates Physical Coding Sublayer functions in order to configure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
 * link. Assumes the hardware has been previously reset and the transmitter
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
 * and receiver are not enabled.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	u32 status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	u32 txcw = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	u32 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	u32 signal = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	DEBUGFUNC("e1000_setup_fiber_serdes_link");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	/* On adapters with a MAC newer than 82544, SWDP 1 will be
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	 * set when the optics detect a signal. On older adapters, it will be
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	 * cleared when there is a signal.  This applies to fiber media only.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	 * If we're on serdes media, adjust the output amplitude to value
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	 * set in the EEPROM.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	if (hw->media_type == e1000_media_type_fiber)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
		signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	ret_val = e1000_adjust_serdes_amplitude(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	/* Take the link out of reset */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	ctrl &= ~(E1000_CTRL_LRST);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	/* Adjust VCO speed to improve BER performance */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	ret_val = e1000_set_vco_speed(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	e1000_config_collision_dist(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	/* Check for a software override of the flow control settings, and setup
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	 * the device accordingly.  If auto-negotiation is enabled, then software
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	 * will have to set the "PAUSE" bits to the correct value in the Tranmsit
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	 * Config Word Register (TXCW) and re-start auto-negotiation.  However, if
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	 * auto-negotiation is disabled, then software will have to manually
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	 * configure the two flow control enable bits in the CTRL register.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	 * The possible values of the "fc" parameter are:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	 *      0:  Flow control is completely disabled
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	 *      1:  Rx flow control is enabled (we can receive pause frames, but
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	 *          not send pause frames).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	 *      2:  Tx flow control is enabled (we can send pause frames but we do
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	 *          not support receiving pause frames).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	switch (hw->fc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	case E1000_FC_NONE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
		/* Flow control is completely disabled by a software over-ride. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	case E1000_FC_RX_PAUSE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		/* RX Flow control is enabled and TX Flow control is disabled by a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		 * software over-ride. Since there really isn't a way to advertise
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
		 * that we are capable of RX Pause ONLY, we will advertise that we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
		 * support both symmetric and asymmetric RX PAUSE. Later, we will
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
		 *  disable the adapter's ability to send PAUSE frames.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	case E1000_FC_TX_PAUSE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		/* TX Flow control is enabled, and RX Flow control is disabled, by a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		 * software over-ride.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	case E1000_FC_FULL:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
		/* Flow control (both RX and TX) is enabled by a software over-ride. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
		DEBUGOUT("Flow control param set incorrectly\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
		return -E1000_ERR_CONFIG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
	/* Since auto-negotiation is enabled, take the link out of reset (the link
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	 * will be in reset, because we previously reset the chip). This will
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	 * restart auto-negotiation.  If auto-negotiation is successful then the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	 * link-up status bit will be set and the flow control enable bits (RFCE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	 * and TFCE) will be set according to their negotiated value.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	DEBUGOUT("Auto-negotiation enabled\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	ew32(TXCW, txcw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	hw->txcw = txcw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	msleep(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	/* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	 * indication in the Device Status Register.  Time-out if a link isn't
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	 * seen in 500 milliseconds seconds (Auto-negotiation should complete in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	 * less than 500 milliseconds even if the other end is doing it in SW).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	 * For internal serdes, we just assume a signal is present, then poll.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	if (hw->media_type == e1000_media_type_internal_serdes ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	    (er32(CTRL) & E1000_CTRL_SWDPIN1) == signal) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
		DEBUGOUT("Looking for Link\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
		for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
			msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
			status = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
			if (status & E1000_STATUS_LU)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
		if (i == (LINK_UP_TIMEOUT / 10)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
			DEBUGOUT("Never got a valid link from auto-neg!!!\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
			hw->autoneg_failed = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
			/* AutoNeg failed to achieve a link, so we'll call
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
			 * e1000_check_for_link. This routine will force the link up if
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
			 * we detect a signal. This will allow us to communicate with
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
			 * non-autonegotiating link partners.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
			ret_val = e1000_check_for_link(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
			if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
				DEBUGOUT("Error while checking for link\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
			hw->autoneg_failed = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
			hw->autoneg_failed = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
			DEBUGOUT("Valid Link Found\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
		DEBUGOUT("No Signal Detected\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
 * e1000_copper_link_preconfig - early configuration for copper
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
 * Make sure we have a valid PHY and change PHY mode before link setup.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
static s32 e1000_copper_link_preconfig(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	DEBUGFUNC("e1000_copper_link_preconfig");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	/* With 82543, we need to force speed and duplex on the MAC equal to what
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	 * the PHY speed and duplex configuration is. In addition, we need to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	 * perform a hardware reset on the PHY to take it out of reset.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	if (hw->mac_type > e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		ctrl |= E1000_CTRL_SLU;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
		ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		ctrl |=
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
		    (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
		ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
		ret_val = e1000_phy_hw_reset(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	/* Make sure we have a valid PHY */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	ret_val = e1000_detect_gig_phy(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		DEBUGOUT("Error, did not detect valid phy.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	/* Set PHY to class A mode (if necessary) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	ret_val = e1000_set_phy_mode(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	if ((hw->mac_type == e1000_82545_rev_3) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	    (hw->mac_type == e1000_82546_rev_3)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
		phy_data |= 0x00000008;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	if (hw->mac_type <= e1000_82543 ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	    hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	    hw->mac_type == e1000_82541_rev_2
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	    || hw->mac_type == e1000_82547_rev_2)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		hw->phy_reset_disable = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
 * e1000_copper_link_igp_setup - Copper link setup for e1000_phy_igp series.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
static s32 e1000_copper_link_igp_setup(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	u32 led_ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	DEBUGFUNC("e1000_copper_link_igp_setup");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	if (hw->phy_reset_disable)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	ret_val = e1000_phy_reset(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		DEBUGOUT("Error Resetting the PHY\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	/* Wait 15ms for MAC to configure PHY from eeprom settings */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	msleep(15);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	/* Configure activity LED after PHY reset */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	led_ctrl = er32(LEDCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	led_ctrl &= IGP_ACTIVITY_LED_MASK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	ew32(LEDCTL, led_ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	/* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	if (hw->phy_type == e1000_phy_igp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		/* disable lplu d3 during driver init */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		ret_val = e1000_set_d3_lplu_state(hw, false);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
			DEBUGOUT("Error Disabling LPLU D3\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	/* Configure mdi-mdix settings */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		hw->dsp_config_state = e1000_dsp_config_disabled;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		/* Force MDI for earlier revs of the IGP PHY */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
		phy_data &=
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
		    ~(IGP01E1000_PSCR_AUTO_MDIX |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		      IGP01E1000_PSCR_FORCE_MDI_MDIX);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
		hw->mdix = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		hw->dsp_config_state = e1000_dsp_config_enabled;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
		switch (hw->mdix) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
		case 1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
			phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
		case 2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
			phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
		case 0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
			phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	/* set auto-master slave resolution settings */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	if (hw->autoneg) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		e1000_ms_type phy_ms_setting = hw->master_slave;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		if (hw->ffe_config_state == e1000_ffe_config_active)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
			hw->ffe_config_state = e1000_ffe_config_enabled;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		if (hw->dsp_config_state == e1000_dsp_config_activated)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
			hw->dsp_config_state = e1000_dsp_config_enabled;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		/* when autonegotiation advertisement is only 1000Mbps then we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		 * should disable SmartSpeed and enable Auto MasterSlave
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		 * resolution as hardware default. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
		if (hw->autoneg_advertised == ADVERTISE_1000_FULL) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
			/* Disable SmartSpeed */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
					       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
						phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
			/* Set auto Master/Slave resolution process */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
			    e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
			phy_data &= ~CR_1000T_MS_ENABLE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
			    e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		/* load defaults for future use */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		    ((phy_data & CR_1000T_MS_VALUE) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		     e1000_ms_force_master :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
		     e1000_ms_force_slave) : e1000_ms_auto;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		switch (phy_ms_setting) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		case e1000_ms_force_master:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
			phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		case e1000_ms_force_slave:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
			phy_data |= CR_1000T_MS_ENABLE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
			phy_data &= ~(CR_1000T_MS_VALUE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		case e1000_ms_auto:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
			phy_data &= ~CR_1000T_MS_ENABLE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
 * e1000_copper_link_mgp_setup - Copper link setup for e1000_phy_m88 series.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
static s32 e1000_copper_link_mgp_setup(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	DEBUGFUNC("e1000_copper_link_mgp_setup");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
	if (hw->phy_reset_disable)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	/* Enable CRS on TX. This must be set for half-duplex operation. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	/* Options:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	 *   MDI/MDI-X = 0 (default)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	 *   0 - Auto for all speeds
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	 *   1 - MDI mode
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	 *   2 - MDI-X mode
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	switch (hw->mdix) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
	case 1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	case 2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	case 3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	case 0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	/* Options:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	 *   disable_polarity_correction = 0 (default)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	 *       Automatic Correction for Reversed Cable Polarity
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	 *   0 - Disabled
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	 *   1 - Enabled
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	if (hw->disable_polarity_correction == 1)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	if (hw->phy_revision < M88E1011_I_REV_4) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		/* Force TX_CLK in the Extended PHY Specific Control Register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		 * to 25MHz clock.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
		    e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
				       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		if ((hw->phy_revision == E1000_REVISION_2) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		    (hw->phy_id == M88E1111_I_PHY_ID)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
			/* Vidalia Phy, set the downshift counter to 5x */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
			phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
			ret_val = e1000_write_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
						      M88E1000_EXT_PHY_SPEC_CTRL,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
						      phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
			/* Configure Master and Slave downshift values */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
				      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
			ret_val = e1000_write_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
						      M88E1000_EXT_PHY_SPEC_CTRL,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
						      phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	/* SW Reset the PHY so all changes take effect */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	ret_val = e1000_phy_reset(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
		DEBUGOUT("Error Resetting the PHY\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
 * e1000_copper_link_autoneg - setup auto-neg
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
 * Setup auto-negotiation and flow control advertisements,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
 * and then perform auto-negotiation.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	DEBUGFUNC("e1000_copper_link_autoneg");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	/* Perform some bounds checking on the hw->autoneg_advertised
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	 * parameter.  If this variable is zero, then set it to the default.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	/* If autoneg_advertised is zero, we assume it was not defaulted
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	 * by the calling code so we set to advertise full capability.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	if (hw->autoneg_advertised == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
		hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
	ret_val = e1000_phy_setup_autoneg(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		DEBUGOUT("Error Setting up Auto-Negotiation\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	DEBUGOUT("Restarting Auto-Neg\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	 * the Auto Neg Restart bit in the PHY control register.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	/* Does the user want to wait for Auto-Neg to complete here, or
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
	 * check at a later time (for example, callback routine).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	if (hw->wait_autoneg_complete) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
		ret_val = e1000_wait_autoneg(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
			DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
			    ("Error while waiting for autoneg to complete\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	hw->get_link_status = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
 * e1000_copper_link_postconfig - post link setup
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
 * Config the MAC and the PHY after link is up.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
 *   1) Set up the MAC to the current PHY speed/duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
 *      if we are on 82543.  If we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
 *      are on newer silicon, we only need to configure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
 *      collision distance in the Transmit Control Register.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
 *   2) Set up flow control on the MAC to that established with
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
 *      the link partner.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
 *   3) Config DSP to improve Gigabit link quality for some PHY revisions.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
static s32 e1000_copper_link_postconfig(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	DEBUGFUNC("e1000_copper_link_postconfig");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	if (hw->mac_type >= e1000_82544) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
		e1000_config_collision_dist(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
		ret_val = e1000_config_mac_to_phy(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
			DEBUGOUT("Error configuring MAC to PHY settings\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	ret_val = e1000_config_fc_after_link_up(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
	if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
		DEBUGOUT("Error Configuring Flow Control\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	/* Config DSP to improve Giga link quality */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	if (hw->phy_type == e1000_phy_igp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
		ret_val = e1000_config_dsp_after_link_change(hw, true);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
			DEBUGOUT("Error Configuring DSP after link up\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
 * e1000_setup_copper_link - phy/speed/duplex setting
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
 * Detects which PHY is present and sets up the speed and duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
static s32 e1000_setup_copper_link(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
	u16 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	DEBUGFUNC("e1000_setup_copper_link");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	/* Check if it is a valid PHY and set PHY mode if necessary. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	ret_val = e1000_copper_link_preconfig(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	if (hw->phy_type == e1000_phy_igp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
		ret_val = e1000_copper_link_igp_setup(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
	} else if (hw->phy_type == e1000_phy_m88) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
		ret_val = e1000_copper_link_mgp_setup(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	if (hw->autoneg) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
		/* Setup autoneg and flow control advertisement
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		 * and perform autonegotiation */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
		ret_val = e1000_copper_link_autoneg(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
		/* PHY will be set to 10H, 10F, 100H,or 100F
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		 * depending on value from forced_speed_duplex. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		DEBUGOUT("Forcing speed and duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		ret_val = e1000_phy_force_speed_duplex(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
			DEBUGOUT("Error Forcing Speed and Duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	/* Check link status. Wait up to 100 microseconds for link to become
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	 * valid.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	for (i = 0; i < 10; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
		if (phy_data & MII_SR_LINK_STATUS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
			/* Config the MAC and PHY after link is up */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
			ret_val = e1000_copper_link_postconfig(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
			DEBUGOUT("Valid link established!!!\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
			return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		udelay(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	DEBUGOUT("Unable to establish link!!!\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
 * e1000_phy_setup_autoneg - phy settings
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
 * Configures PHY autoneg and flow control advertisement settings
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	u16 mii_autoneg_adv_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	u16 mii_1000t_ctrl_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	DEBUGFUNC("e1000_phy_setup_autoneg");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	/* Read the MII 1000Base-T Control Register (Address 9). */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	    e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	/* Need to parse both autoneg_advertised and fc and set up
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	 * the appropriate PHY registers.  First we will parse for
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
	 * autoneg_advertised software override.  Since we can advertise
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	 * a plethora of combinations, we need to check each bit
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	 * individually.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	 * the  1000Base-T Control Register (Address 9).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	DEBUGOUT1("autoneg_advertised %x\n", hw->autoneg_advertised);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	/* Do we want to advertise 10 Mb Half Duplex? */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
		DEBUGOUT("Advertise 10mb Half duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	/* Do we want to advertise 10 Mb Full Duplex? */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		DEBUGOUT("Advertise 10mb Full duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
	/* Do we want to advertise 100 Mb Half Duplex? */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
		DEBUGOUT("Advertise 100mb Half duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	/* Do we want to advertise 100 Mb Full Duplex? */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		DEBUGOUT("Advertise 100mb Full duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
		    ("Advertise 1000mb Half duplex requested, request denied!\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	/* Do we want to advertise 1000 Mb Full Duplex? */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		DEBUGOUT("Advertise 1000mb Full duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	/* Check for a software override of the flow control settings, and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	 * setup the PHY advertisement registers accordingly.  If
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	 * auto-negotiation is enabled, then software will have to set the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	 * "PAUSE" bits to the correct value in the Auto-Negotiation
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
	 * The possible values of the "fc" parameter are:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	 *      0:  Flow control is completely disabled
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	 *      1:  Rx flow control is enabled (we can receive pause frames
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
	 *          but not send pause frames).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	 *      2:  Tx flow control is enabled (we can send pause frames
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	 *          but we do not support receiving pause frames).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	 *  other:  No software override.  The flow control configuration
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	 *          in the EEPROM is used.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	switch (hw->fc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	case E1000_FC_NONE:	/* 0 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		/* Flow control (RX & TX) is completely disabled by a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		 * software over-ride.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	case E1000_FC_RX_PAUSE:	/* 1 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		/* RX Flow control is enabled, and TX Flow control is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		 * disabled, by a software over-ride.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		/* Since there really isn't a way to advertise that we are
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		 * capable of RX Pause ONLY, we will advertise that we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		 * support both symmetric and asymmetric RX PAUSE.  Later
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		 * (in e1000_config_fc_after_link_up) we will disable the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		 *hw's ability to send PAUSE frames.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	case E1000_FC_TX_PAUSE:	/* 2 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
		/* TX Flow control is enabled, and RX Flow control is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		 * disabled, by a software over-ride.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
	case E1000_FC_FULL:	/* 3 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
		/* Flow control (both RX and TX) is enabled by a software
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		 * over-ride.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
		DEBUGOUT("Flow control param set incorrectly\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
		return -E1000_ERR_CONFIG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
	DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
 * e1000_phy_force_speed_duplex - force link settings
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
 * Force PHY speed and duplex settings to hw->forced_speed_duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	u16 mii_ctrl_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	u16 mii_status_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	u16 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	DEBUGFUNC("e1000_phy_force_speed_duplex");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	/* Turn off Flow control if we are forcing speed and duplex. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	hw->fc = E1000_FC_NONE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	DEBUGOUT1("hw->fc = %d\n", hw->fc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	/* Read the Device Control Register. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
	ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
	/* Set the bits to Force Speed and Duplex in the Device Ctrl Reg. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
	ctrl &= ~(DEVICE_SPEED_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	/* Clear the Auto Speed Detect Enable bit. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
	ctrl &= ~E1000_CTRL_ASDE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	/* Read the MII Control Register. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
	/* We need to disable autoneg in order to force link and duplex. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	/* Are we forcing Full or Half Duplex? */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	if (hw->forced_speed_duplex == e1000_100_full ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
	    hw->forced_speed_duplex == e1000_10_full) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		/* We want to force full duplex so we SET the full duplex bits in the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		 * Device and MII Control Registers.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		ctrl |= E1000_CTRL_FD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		mii_ctrl_reg |= MII_CR_FULL_DUPLEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
		DEBUGOUT("Full Duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		/* We want to force half duplex so we CLEAR the full duplex bits in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		 * the Device and MII Control Registers.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		ctrl &= ~E1000_CTRL_FD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		mii_ctrl_reg &= ~MII_CR_FULL_DUPLEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		DEBUGOUT("Half Duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
	/* Are we forcing 100Mbps??? */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
	if (hw->forced_speed_duplex == e1000_100_full ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	    hw->forced_speed_duplex == e1000_100_half) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		/* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		ctrl |= E1000_CTRL_SPD_100;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		mii_ctrl_reg |= MII_CR_SPEED_100;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
		DEBUGOUT("Forcing 100mb ");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
		/* Set the 10Mb bit and turn off the 1000Mb and 100Mb bits. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
		mii_ctrl_reg |= MII_CR_SPEED_10;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
		mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		DEBUGOUT("Forcing 10mb ");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	e1000_config_collision_dist(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	/* Write the configured values back to the Device Control Reg. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	if (hw->phy_type == e1000_phy_m88) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
		/* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		 * forced whenever speed are duplex are forced.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
		DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
		/* Need to reset the PHY or these changes will be ignored */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
		mii_ctrl_reg |= MII_CR_RESET;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
		/* Disable MDI-X support for 10/100 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
		/* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		 * forced whenever speed or duplex are forced.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
		    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
		phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
		    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
	/* Write back the modified PHY MII control register. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	udelay(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
	/* The wait_autoneg_complete flag may be a little misleading here.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	 * Since we are forcing speed and duplex, Auto-Neg is not enabled.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	 * But we do want to delay for a period while forcing only so we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	 * don't generate false No Link messages.  So we will wait here
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	 * only if the user has set wait_autoneg_complete to 1, which is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	 * the default.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	if (hw->wait_autoneg_complete) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
		/* We will wait for autoneg to complete. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
		DEBUGOUT("Waiting for forced speed/duplex link.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		mii_status_reg = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		/* We will wait for autoneg to complete or 4.5 seconds to expire. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
		for (i = PHY_FORCE_TIME; i > 0; i--) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
			/* Read the MII Status Register and wait for Auto-Neg Complete bit
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
			 * to be set.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
			if (mii_status_reg & MII_SR_LINK_STATUS)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
			msleep(100);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		if ((i == 0) && (hw->phy_type == e1000_phy_m88)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
			/* We didn't get link.  Reset the DSP and wait again for link. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
			ret_val = e1000_phy_reset_dsp(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
			if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
				DEBUGOUT("Error Resetting PHY DSP\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
		/* This loop will early-out if the link condition has been met.  */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		for (i = PHY_FORCE_TIME; i > 0; i--) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
			if (mii_status_reg & MII_SR_LINK_STATUS)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
			msleep(100);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
			/* Read the MII Status Register and wait for Auto-Neg Complete bit
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
			 * to be set.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
	if (hw->phy_type == e1000_phy_m88) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		/* Because we reset the PHY above, we need to re-force TX_CLK in the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		 * Extended PHY Specific Control Register to 25MHz clock.  This value
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		 * defaults back to a 2.5MHz clock when the PHY is reset.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
		    e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
				       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
		    e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
					phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
		/* In addition, because of the s/w reset above, we need to enable CRS on
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		 * TX.  This must be set for both full and half duplex operation.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
		phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
		if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		    && (!hw->autoneg)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
		    && (hw->forced_speed_duplex == e1000_10_full
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
			|| hw->forced_speed_duplex == e1000_10_half)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
			ret_val = e1000_polarity_reversal_workaround(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
 * e1000_config_collision_dist - set collision distance register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
 * Sets the collision distance in the Transmit Control register.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
 * Link should have been established previously. Reads the speed and duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
 * information from the Device Status register.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
void e1000_config_collision_dist(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
	u32 tctl, coll_dist;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
	DEBUGFUNC("e1000_config_collision_dist");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
	if (hw->mac_type < e1000_82543)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
		coll_dist = E1000_COLLISION_DISTANCE_82542;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		coll_dist = E1000_COLLISION_DISTANCE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	tctl = er32(TCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	tctl &= ~E1000_TCTL_COLD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	tctl |= coll_dist << E1000_COLD_SHIFT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
	ew32(TCTL, tctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
 * e1000_config_mac_to_phy - sync phy and mac settings
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
 * @mii_reg: data to write to the MII control register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
 * Sets MAC speed and duplex settings to reflect the those in the PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
 * The contents of the PHY register containing the needed information need to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
 * be passed in.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
	DEBUGFUNC("e1000_config_mac_to_phy");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	/* 82544 or newer MAC, Auto Speed Detection takes care of
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	 * MAC speed/duplex configuration.*/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
	if (hw->mac_type >= e1000_82544)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	/* Read the Device Control Register and set the bits to Force Speed
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	 * and Duplex.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
	ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
	ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	/* Set up duplex in the Device Control and Transmit Control
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	 * registers depending on negotiated values.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	if (phy_data & M88E1000_PSSR_DPLX)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		ctrl |= E1000_CTRL_FD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
		ctrl &= ~E1000_CTRL_FD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
	e1000_config_collision_dist(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
	/* Set up speed in the Device Control register depending on
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	 * negotiated values.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
		ctrl |= E1000_CTRL_SPD_1000;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
	else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
		ctrl |= E1000_CTRL_SPD_100;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	/* Write the configured values back to the Device Control Reg. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
 * e1000_force_mac_fc - force flow control settings
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
 * Forces the MAC's flow control settings.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
 * Sets the TFCE and RFCE bits in the device control register to reflect
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
 * the adapter settings. TFCE and RFCE need to be explicitly set by
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
 * software when a Copper PHY is used because autonegotiation is managed
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
 * by the PHY rather than the MAC. Software must also configure these
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
 * bits when link is forced on a fiber connection.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
s32 e1000_force_mac_fc(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	DEBUGFUNC("e1000_force_mac_fc");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	/* Get the current configuration of the Device Control Register */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	/* Because we didn't get link via the internal auto-negotiation
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	 * mechanism (we either forced link or we got link via PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	 * auto-neg), we have to manually enable/disable transmit an
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	 * receive flow control.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
	 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
	 * The "Case" statement below enables/disable flow control
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	 * according to the "hw->fc" parameter.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
	 * The possible values of the "fc" parameter are:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	 *      0:  Flow control is completely disabled
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	 *      1:  Rx flow control is enabled (we can receive pause
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	 *          frames but not send pause frames).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	 *      2:  Tx flow control is enabled (we can send pause frames
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	 *          frames but we do not receive pause frames).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
	 *      3:  Both Rx and TX flow control (symmetric) is enabled.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	 *  other:  No other values should be possible at this point.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	switch (hw->fc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	case E1000_FC_NONE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
	case E1000_FC_RX_PAUSE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
		ctrl &= (~E1000_CTRL_TFCE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
		ctrl |= E1000_CTRL_RFCE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	case E1000_FC_TX_PAUSE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
		ctrl &= (~E1000_CTRL_RFCE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		ctrl |= E1000_CTRL_TFCE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	case E1000_FC_FULL:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
		DEBUGOUT("Flow control param set incorrectly\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		return -E1000_ERR_CONFIG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	/* Disable TX Flow Control for 82542 (rev 2.0) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
	if (hw->mac_type == e1000_82542_rev2_0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
		ctrl &= (~E1000_CTRL_TFCE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
 * e1000_config_fc_after_link_up - configure flow control after autoneg
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
 * Configures flow control settings after link is established
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
 * Should be called immediately after a valid link has been established.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
 * Forces MAC flow control settings if link was forced. When in MII/GMII mode
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
 * and autonegotiation is enabled, the MAC flow control settings will be set
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
 * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
 * and RFCE bits will be automatically set to the negotiated flow control mode.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	u16 mii_status_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	u16 mii_nway_adv_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
	u16 mii_nway_lp_ability_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
	u16 speed;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	u16 duplex;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	DEBUGFUNC("e1000_config_fc_after_link_up");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
	/* Check for the case where we have fiber media and auto-neg failed
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	 * so we had to force link.  In this case, we need to force the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	 * configuration of the MAC to match the "fc" parameter.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	    || ((hw->media_type == e1000_media_type_internal_serdes)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
		&& (hw->autoneg_failed))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	    || ((hw->media_type == e1000_media_type_copper)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
		&& (!hw->autoneg))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		ret_val = e1000_force_mac_fc(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
			DEBUGOUT("Error forcing flow control settings\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	/* Check for the case where we have copper media and auto-neg is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	 * enabled.  In this case, we need to check and see if Auto-Neg
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	 * has completed, and if so, how the PHY and link partner has
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	 * flow control configured.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	if ((hw->media_type == e1000_media_type_copper) && hw->autoneg) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
		/* Read the MII Status Register and check to see if AutoNeg
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
		 * has completed.  We read this twice because this reg has
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
		 * some "sticky" (latched) bits.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
		if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
			/* The AutoNeg process has completed, so we now need to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
			 * read both the Auto Negotiation Advertisement Register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
			 * (Address 4) and the Auto_Negotiation Base Page Ability
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
			 * Register (Address 5) to determine how flow control was
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
			 * negotiated.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
			ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
						     &mii_nway_adv_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
			ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
						     &mii_nway_lp_ability_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
			/* Two bits in the Auto Negotiation Advertisement Register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
			 * (Address 4) and two bits in the Auto Negotiation Base
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
			 * Page Ability Register (Address 5) determine flow control
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
			 * for both the PHY and the link partner.  The following
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
			 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
			 * 1999, describes these PAUSE resolution bits and how flow
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
			 * control is determined based upon these settings.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
			 * NOTE:  DC = Don't Care
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
			 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
			 *   LOCAL DEVICE  |   LINK PARTNER
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
			 *-------|---------|-------|---------|--------------------
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
			 *   0   |    0    |  DC   |   DC    | E1000_FC_NONE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
			 *   0   |    1    |   0   |   DC    | E1000_FC_NONE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
			 *   0   |    1    |   1   |    0    | E1000_FC_NONE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
			 *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
			 *   1   |    0    |   0   |   DC    | E1000_FC_NONE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
			 *   1   |    1    |   0   |    0    | E1000_FC_NONE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
			 *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
			 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			/* Are both PAUSE bits set to 1?  If so, this implies
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
			 * Symmetric Flow Control is enabled at both ends.  The
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
			 * ASM_DIR bits are irrelevant per the spec.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
			 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
			 * For Symmetric Flow Control:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
			 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
			 *   LOCAL DEVICE  |   LINK PARTNER
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
			 *-------|---------|-------|---------|--------------------
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
			 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
			if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
			    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
				/* Now we need to check if the user selected RX ONLY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
				 * of pause frames.  In this case, we had to advertise
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
				 * FULL flow control because we could not advertise RX
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
				 * ONLY. Hence, we must now check to see if we need to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
				 * turn OFF  the TRANSMISSION of PAUSE frames.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
				 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
				if (hw->original_fc == E1000_FC_FULL) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
					hw->fc = E1000_FC_FULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
					DEBUGOUT("Flow Control = FULL.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
				} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
					hw->fc = E1000_FC_RX_PAUSE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
					DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
					    ("Flow Control = RX PAUSE frames only.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
				}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
			/* For receiving PAUSE frames ONLY.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
			 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
			 *   LOCAL DEVICE  |   LINK PARTNER
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
			 *-------|---------|-------|---------|--------------------
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
			 *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
			 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
			else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
				 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
			{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
				hw->fc = E1000_FC_TX_PAUSE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
				DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
				    ("Flow Control = TX PAUSE frames only.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
			/* For transmitting PAUSE frames ONLY.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
			 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
			 *   LOCAL DEVICE  |   LINK PARTNER
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
			 *-------|---------|-------|---------|--------------------
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
			 *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
			 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
			else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
				 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
			{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
				hw->fc = E1000_FC_RX_PAUSE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
				DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
				    ("Flow Control = RX PAUSE frames only.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
			/* Per the IEEE spec, at this point flow control should be
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
			 * disabled.  However, we want to consider that we could
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
			 * be connected to a legacy switch that doesn't advertise
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
			 * desired flow control, but can be forced on the link
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
			 * partner.  So if we advertised no flow control, that is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
			 * what we will resolve to.  If we advertised some kind of
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
			 * receive capability (Rx Pause Only or Full Flow Control)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
			 * and the link partner advertised none, we will configure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
			 * ourselves to enable Rx Flow Control only.  We can do
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
			 * this safely for two reasons:  If the link partner really
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
			 * didn't want flow control enabled, and we enable Rx, no
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
			 * harm done since we won't be receiving any PAUSE frames
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
			 * anyway.  If the intent on the link partner was to have
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
			 * flow control enabled, then by us enabling RX only, we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
			 * can at least receive pause frames and process them.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
			 * This is a good idea because in most cases, since we are
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
			 * predominantly a server NIC, more times than not we will
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
			 * be asked to delay transmission of packets than asking
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
			 * our link partner to pause transmission of frames.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
			else if ((hw->original_fc == E1000_FC_NONE ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
				  hw->original_fc == E1000_FC_TX_PAUSE) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
				 hw->fc_strict_ieee) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
				hw->fc = E1000_FC_NONE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
				DEBUGOUT("Flow Control = NONE.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
			} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
				hw->fc = E1000_FC_RX_PAUSE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
				DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
				    ("Flow Control = RX PAUSE frames only.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
			/* Now we need to do one last check...  If we auto-
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
			 * negotiated to HALF DUPLEX, flow control should not be
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
			 * enabled per IEEE 802.3 spec.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
				DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
				    ("Error getting link speed and duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
			if (duplex == HALF_DUPLEX)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
				hw->fc = E1000_FC_NONE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
			/* Now we call a subroutine to actually force the MAC
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
			 * controller to use the correct flow control settings.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
			ret_val = e1000_force_mac_fc(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
			if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
				DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
				    ("Error forcing flow control settings\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
			DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
			    ("Copper PHY and Auto Neg has not completed.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
 * e1000_check_for_serdes_link_generic - Check for link (Serdes)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
 * @hw: pointer to the HW structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
 * Checks for link up on the hardware.  If link is not up and we have
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
 * a signal, then we need to force link up.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
static s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	u32 rxcw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	u32 status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	s32 ret_val = E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	DEBUGFUNC("e1000_check_for_serdes_link_generic");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
	status = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	rxcw = er32(RXCW);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	/*
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
	 * If we don't have link (auto-negotiation failed or link partner
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	 * cannot auto-negotiate), and our link partner is not trying to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	 * auto-negotiate with us (we are receiving idles or data),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	 * we need to force link up. We also need to give auto-negotiation
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	 * time to complete.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
		if (hw->autoneg_failed == 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
			hw->autoneg_failed = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
			goto out;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
		DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
		/* Disable auto-negotiation in the TXCW register */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
		ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
		/* Force link-up and also force full-duplex. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
		ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
		ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
		/* Configure Flow Control after forcing link up. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
		ret_val = e1000_config_fc_after_link_up(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
			DEBUGOUT("Error configuring flow control\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
			goto out;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
		/*
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
		 * If we are forcing link and we are receiving /C/ ordered
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
		 * sets, re-enable auto-negotiation in the TXCW register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
		 * and disable forced link in the Device Control register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
		 * in an attempt to auto-negotiate with our link partner.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
		DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		ew32(TXCW, hw->txcw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
		hw->serdes_has_link = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
		/*
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
		 * If we force link for non-auto-negotiation switch, check
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
		 * link status based on MAC synchronization for internal
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
		 * serdes media type.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
		/* SYNCH bit and IV bit are sticky. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
		udelay(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
		rxcw = er32(RXCW);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
		if (rxcw & E1000_RXCW_SYNCH) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
			if (!(rxcw & E1000_RXCW_IV)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
				hw->serdes_has_link = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
				DEBUGOUT("SERDES: Link up - forced.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
			hw->serdes_has_link = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
			DEBUGOUT("SERDES: Link down - force failed.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	if (E1000_TXCW_ANE & er32(TXCW)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
		status = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
		if (status & E1000_STATUS_LU) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
			/* SYNCH bit and IV bit are sticky, so reread rxcw. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
			udelay(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
			rxcw = er32(RXCW);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
			if (rxcw & E1000_RXCW_SYNCH) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
				if (!(rxcw & E1000_RXCW_IV)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
					hw->serdes_has_link = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
					DEBUGOUT("SERDES: Link up - autoneg "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
						 "completed successfully.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
				} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
					hw->serdes_has_link = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
					DEBUGOUT("SERDES: Link down - invalid"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
						 "codewords detected in autoneg.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
				}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
			} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
				hw->serdes_has_link = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
				DEBUGOUT("SERDES: Link down - no sync.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
			hw->serdes_has_link = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
			DEBUGOUT("SERDES: Link down - autoneg failed\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
      out:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
 * e1000_check_for_link
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
 * Checks to see if the link status of the hardware has changed.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
 * Called by any function that needs to check the link status of the adapter.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
s32 e1000_check_for_link(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	u32 rxcw = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	u32 status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	u32 rctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	u32 icr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	u32 signal = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
	DEBUGFUNC("e1000_check_for_link");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
	ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	status = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
	/* On adapters with a MAC newer than 82544, SW Definable pin 1 will be
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	 * set when the optics detect a signal. On older adapters, it will be
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	 * cleared when there is a signal.  This applies to fiber media only.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	if ((hw->media_type == e1000_media_type_fiber) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	    (hw->media_type == e1000_media_type_internal_serdes)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
		rxcw = er32(RXCW);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
		if (hw->media_type == e1000_media_type_fiber) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
			signal =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
			    (hw->mac_type >
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
			     e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
			if (status & E1000_STATUS_LU)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
				hw->get_link_status = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
	/* If we have a copper PHY then we only want to go out to the PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	 * registers to see if Auto-Neg has completed and/or if our link
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	 * status has changed.  The get_link_status flag will be set if we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
	 * receive a Link Status Change interrupt or we have Rx Sequence
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	 * Errors.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
		/* First we want to see if the MII Status Register reports
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		 * link.  If so, then we want to get the current speed/duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		 * of the PHY.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
		 * Read the register twice since the link bit is sticky.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
		if (phy_data & MII_SR_LINK_STATUS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
			hw->get_link_status = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
			/* Check if there was DownShift, must be checked immediately after
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
			 * link-up */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
			e1000_check_downshift(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
			/* If we are on 82544 or 82543 silicon and speed/duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
			 * are forced to 10H or 10F, then we will implement the polarity
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
			 * reversal workaround.  We disable interrupts first, and upon
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
			 * returning, place the devices interrupt state to its previous
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
			 * value except for the link status change interrupt which will
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
			 * happen due to the execution of this workaround.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
			if ((hw->mac_type == e1000_82544
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
			     || hw->mac_type == e1000_82543) && (!hw->autoneg)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
			    && (hw->forced_speed_duplex == e1000_10_full
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
				|| hw->forced_speed_duplex == e1000_10_half)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
				ew32(IMC, 0xffffffff);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
				ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
				    e1000_polarity_reversal_workaround(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
				icr = er32(ICR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
				ew32(ICS, (icr & ~E1000_ICS_LSC));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
				ew32(IMS, IMS_ENABLE_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
			/* No link detected */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
			e1000_config_dsp_after_link_change(hw, false);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
			return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
		/* If we are forcing speed/duplex, then we simply return since
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
		 * we have already determined whether we have link or not.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		if (!hw->autoneg)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
			return -E1000_ERR_CONFIG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
		/* optimize the dsp settings for the igp phy */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
		e1000_config_dsp_after_link_change(hw, true);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
		/* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
		 * have Si on board that is 82544 or newer, Auto
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		 * Speed Detection takes care of MAC speed/duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
		 * configuration.  So we only need to configure Collision
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
		 * Distance in the MAC.  Otherwise, we need to force
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
		 * speed/duplex on the MAC to the current PHY speed/duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
		 * settings.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
		if (hw->mac_type >= e1000_82544)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
			e1000_config_collision_dist(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
		else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
			ret_val = e1000_config_mac_to_phy(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
			if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
				DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
				    ("Error configuring MAC to PHY settings\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
		/* Configure Flow Control now that Auto-Neg has completed. First, we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
		 * need to restore the desired flow control settings because we may
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
		 * have had to re-autoneg with a different link partner.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
		ret_val = e1000_config_fc_after_link_up(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
			DEBUGOUT("Error configuring flow control\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
		/* At this point we know that we are on copper and we have
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
		 * auto-negotiated link.  These are conditions for checking the link
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
		 * partner capability register.  We use the link speed to determine if
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
		 * TBI compatibility needs to be turned on or off.  If the link is not
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
		 * at gigabit speed, then TBI compatibility is not needed.  If we are
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
		 * at gigabit speed, we turn on TBI compatibility.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
		if (hw->tbi_compatibility_en) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
			u16 speed, duplex;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
			if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
				DEBUGOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
				    ("Error getting link speed and duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
			if (speed != SPEED_1000) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
				/* If link speed is not set to gigabit speed, we do not need
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
				 * to enable TBI compatibility.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
				 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
				if (hw->tbi_compatibility_on) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
					/* If we previously were in the mode, turn it off. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
					rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
					rctl &= ~E1000_RCTL_SBP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
					ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
					hw->tbi_compatibility_on = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
				}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
			} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
				/* If TBI compatibility is was previously off, turn it on. For
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
				 * compatibility with a TBI link partner, we will store bad
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
				 * packets. Some frames have an additional byte on the end and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
				 * will look like CRC errors to to the hardware.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
				 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
				if (!hw->tbi_compatibility_on) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
					hw->tbi_compatibility_on = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
					rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
					rctl |= E1000_RCTL_SBP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
					ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
				}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
	if ((hw->media_type == e1000_media_type_fiber) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
	    (hw->media_type == e1000_media_type_internal_serdes))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
		e1000_check_for_serdes_link_generic(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
 * e1000_get_speed_and_duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
 * @speed: Speed of the connection
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
 * @duplex: Duplex setting of the connection
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
 * Detects the current speed and duplex settings of the hardware.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
	u32 status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	DEBUGFUNC("e1000_get_speed_and_duplex");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	if (hw->mac_type >= e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		status = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
		if (status & E1000_STATUS_SPEED_1000) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
			*speed = SPEED_1000;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
			DEBUGOUT("1000 Mbs, ");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
		} else if (status & E1000_STATUS_SPEED_100) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
			*speed = SPEED_100;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
			DEBUGOUT("100 Mbs, ");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
			*speed = SPEED_10;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
			DEBUGOUT("10 Mbs, ");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
		if (status & E1000_STATUS_FD) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
			*duplex = FULL_DUPLEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
			DEBUGOUT("Full Duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
			*duplex = HALF_DUPLEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
			DEBUGOUT(" Half Duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		DEBUGOUT("1000 Mbs, Full Duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
		*speed = SPEED_1000;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
		*duplex = FULL_DUPLEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	/* IGP01 PHY may advertise full duplex operation after speed downgrade even
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	 * if it is operating at half duplex.  Here we set the duplex settings to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	 * match the duplex in the link partner's capabilities.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
	if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		if (!(phy_data & NWAY_ER_LP_NWAY_CAPS))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
			*duplex = HALF_DUPLEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
			    e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			if ((*speed == SPEED_100
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
			     && !(phy_data & NWAY_LPAR_100TX_FD_CAPS))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
			    || (*speed == SPEED_10
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
				&& !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
				*duplex = HALF_DUPLEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
 * e1000_wait_autoneg
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
 * Blocks until autoneg completes or times out (~4.5 seconds)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
static s32 e1000_wait_autoneg(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	u16 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
	DEBUGFUNC("e1000_wait_autoneg");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	DEBUGOUT("Waiting for Auto-Neg to complete.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
	/* We will wait for autoneg to complete or 4.5 seconds to expire. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
	for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
		/* Read the MII Status Register and wait for Auto-Neg
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
		 * Complete bit to be set.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
		if (phy_data & MII_SR_AUTONEG_COMPLETE) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
			return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		msleep(100);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
 * e1000_raise_mdi_clk - Raises the Management Data Clock
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
 * @ctrl: Device control register's current value
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	/* Raise the clock input to the Management Data Clock (by setting the MDC
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	 * bit), and then delay 10 microseconds.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
	ew32(CTRL, (*ctrl | E1000_CTRL_MDC));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
	udelay(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
 * e1000_lower_mdi_clk - Lowers the Management Data Clock
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
 * @ctrl: Device control register's current value
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
	/* Lower the clock input to the Management Data Clock (by clearing the MDC
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
	 * bit), and then delay 10 microseconds.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
	ew32(CTRL, (*ctrl & ~E1000_CTRL_MDC));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
	udelay(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
 * e1000_shift_out_mdi_bits - Shifts data bits out to the PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
 * @data: Data to send out to the PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
 * @count: Number of bits to shift out
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
 * Bits are shifted out in MSB to LSB order.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data, u16 count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	u32 mask;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
	/* We need to shift "count" number of bits out to the PHY. So, the value
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	 * in the "data" parameter will be shifted out to the PHY one bit at a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	 * time. In order to do this, "data" must be broken down into bits.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	mask = 0x01;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
	mask <<= (count - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	/* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	while (mask) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
		/* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
		 * then raising and lowering the Management Data Clock. A "0" is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
		 * shifted out to the PHY by setting the MDIO bit to "0" and then
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
		 * raising and lowering the clock.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
		if (data & mask)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
			ctrl |= E1000_CTRL_MDIO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
			ctrl &= ~E1000_CTRL_MDIO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
		ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		udelay(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		e1000_raise_mdi_clk(hw, &ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
		e1000_lower_mdi_clk(hw, &ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
		mask = mask >> 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
 * e1000_shift_in_mdi_bits - Shifts data bits in from the PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
 * Bits are shifted in in MSB to LSB order.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	u16 data = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	u8 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
	/* In order to read a register from the PHY, we need to shift in a total
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	 * of 18 bits from the PHY. The first two bit (turnaround) times are used
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
	 * to avoid contention on the MDIO pin when a read operation is performed.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	 * These two bits are ignored by us and thrown away. Bits are "shifted in"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	 * by raising the input to the Management Data Clock (setting the MDC bit),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	 * and then reading the value of the MDIO bit.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
	ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
	/* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
	ctrl &= ~E1000_CTRL_MDIO_DIR;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
	ctrl &= ~E1000_CTRL_MDIO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	/* Raise and Lower the clock before reading in the data. This accounts for
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
	 * the turnaround bits. The first clock occurred when we clocked out the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	 * last bit of the Register Address.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	e1000_raise_mdi_clk(hw, &ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	e1000_lower_mdi_clk(hw, &ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	for (data = 0, i = 0; i < 16; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		data = data << 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
		e1000_raise_mdi_clk(hw, &ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
		/* Check to see if we shifted in a "1". */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
		if (ctrl & E1000_CTRL_MDIO)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
			data |= 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
		e1000_lower_mdi_clk(hw, &ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	e1000_raise_mdi_clk(hw, &ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
	e1000_lower_mdi_clk(hw, &ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
	return data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
 * e1000_read_phy_reg - read a phy register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
 * @reg_addr: address of the PHY register to read
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
 * Reads the value from a PHY register, if the value is on a specific non zero
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
 * page, sets the page first.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	u32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	DEBUGFUNC("e1000_read_phy_reg");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
	if ((hw->phy_type == e1000_phy_igp) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
						 (u16) reg_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
					phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
				 u16 *phy_data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
	u32 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	u32 mdic = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	const u32 phy_addr = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
	DEBUGFUNC("e1000_read_phy_reg_ex");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
		DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
		return -E1000_ERR_PARAM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	if (hw->mac_type > e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
		/* Set up Op-code, Phy Address, and register address in the MDI
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
		 * Control register.  The MAC will take care of interfacing with the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		 * PHY to retrieve the desired data.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
		mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
			(phy_addr << E1000_MDIC_PHY_SHIFT) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
			(E1000_MDIC_OP_READ));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
		ew32(MDIC, mdic);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
		/* Poll the ready bit to see if the MDI read completed */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
		for (i = 0; i < 64; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
			udelay(50);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
			mdic = er32(MDIC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
			if (mdic & E1000_MDIC_READY)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
		if (!(mdic & E1000_MDIC_READY)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
			DEBUGOUT("MDI Read did not complete\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
			return -E1000_ERR_PHY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
		if (mdic & E1000_MDIC_ERROR) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
			DEBUGOUT("MDI Error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
			return -E1000_ERR_PHY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
		*phy_data = (u16) mdic;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
		/* We must first send a preamble through the MDIO pin to signal the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		 * beginning of an MII instruction.  This is done by sending 32
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
		 * consecutive "1" bits.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
		/* Now combine the next few fields that are required for a read
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
		 * operation.  We use this method instead of calling the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
		 * e1000_shift_out_mdi_bits routine five different times. The format of
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
		 * a MII read instruction consists of a shift out of 14 bits and is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		 * defined as follows:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		 *    <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
		 * followed by a shift in of 18 bits.  This first two bits shifted in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
		 * are TurnAround bits used to avoid contention on the MDIO pin when a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
		 * READ operation is performed.  These two bits are thrown away
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
		 * followed by a shift in of 16 bits which contains the desired data.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
		mdic = ((reg_addr) | (phy_addr << 5) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
			(PHY_OP_READ << 10) | (PHY_SOF << 12));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
		e1000_shift_out_mdi_bits(hw, mdic, 14);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
		/* Now that we've shifted out the read command to the MII, we need to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		 * "shift in" the 16-bit value (18 total bits) of the requested PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
		 * register address.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
		*phy_data = e1000_shift_in_mdi_bits(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
 * e1000_write_phy_reg - write a phy register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
 * @reg_addr: address of the PHY register to write
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
 * @data: data to write to the PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
 * Writes a value to a PHY register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	u32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	DEBUGFUNC("e1000_write_phy_reg");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
	if ((hw->phy_type == e1000_phy_igp) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
						 (u16) reg_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
	ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
					 phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
				  u16 phy_data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	u32 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
	u32 mdic = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	const u32 phy_addr = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	DEBUGFUNC("e1000_write_phy_reg_ex");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
		DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
		return -E1000_ERR_PARAM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	if (hw->mac_type > e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
		/* Set up Op-code, Phy Address, register address, and data intended
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
		 * for the PHY register in the MDI Control register.  The MAC will take
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
		 * care of interfacing with the PHY to send the desired data.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
		mdic = (((u32) phy_data) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
			(reg_addr << E1000_MDIC_REG_SHIFT) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
			(phy_addr << E1000_MDIC_PHY_SHIFT) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
			(E1000_MDIC_OP_WRITE));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
		ew32(MDIC, mdic);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
		/* Poll the ready bit to see if the MDI read completed */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
		for (i = 0; i < 641; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
			udelay(5);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
			mdic = er32(MDIC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
			if (mdic & E1000_MDIC_READY)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
		if (!(mdic & E1000_MDIC_READY)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
			DEBUGOUT("MDI Write did not complete\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
			return -E1000_ERR_PHY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
		/* We'll need to use the SW defined pins to shift the write command
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
		 * out to the PHY. We first send a preamble to the PHY to signal the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
		 * beginning of the MII instruction.  This is done by sending 32
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
		 * consecutive "1" bits.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
		/* Now combine the remaining required fields that will indicate a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
		 * write operation. We use this method instead of calling the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
		 * e1000_shift_out_mdi_bits routine for each field in the command. The
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
		 * format of a MII write instruction is as follows:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
		 * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
		mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
			(PHY_OP_WRITE << 12) | (PHY_SOF << 14));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		mdic <<= 16;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		mdic |= (u32) phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
		e1000_shift_out_mdi_bits(hw, mdic, 32);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
 * e1000_phy_hw_reset - reset the phy, hardware style
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
 * Returns the PHY to the power-on reset state
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
s32 e1000_phy_hw_reset(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
	u32 ctrl, ctrl_ext;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
	u32 led_ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
	DEBUGFUNC("e1000_phy_hw_reset");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	DEBUGOUT("Resetting Phy...\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
	if (hw->mac_type > e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
		/* Read the device control register and assert the E1000_CTRL_PHY_RST
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
		 * bit. Then, take it out of reset.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
		 * For e1000 hardware, we delay for 10ms between the assert
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		 * and deassert.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
		ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
		/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
		 * bit to put the PHY into reset. Then, take it out of reset.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		ctrl_ext = er32(CTRL_EXT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		ew32(CTRL_EXT, ctrl_ext);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
		msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
		ew32(CTRL_EXT, ctrl_ext);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	udelay(150);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		/* Configure activity LED after PHY reset */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		led_ctrl = er32(LEDCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
		ew32(LEDCTL, led_ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	/* Wait for FW to finish PHY configuration. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	ret_val = e1000_get_phy_cfg_done(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
	if (ret_val != E1000_SUCCESS)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
 * e1000_phy_reset - reset the phy to commit settings
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
 * Resets the PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
 * Sets bit 15 of the MII Control register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
s32 e1000_phy_reset(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
	DEBUGFUNC("e1000_phy_reset");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
	switch (hw->phy_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	case e1000_phy_igp:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
		ret_val = e1000_phy_hw_reset(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
		ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
		phy_data |= MII_CR_RESET;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
		ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
		udelay(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	if (hw->phy_type == e1000_phy_igp)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
		e1000_phy_init_script(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
 * e1000_detect_gig_phy - check the phy type
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
 * Probes the expected PHY address for known PHY IDs
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
static s32 e1000_detect_gig_phy(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
	s32 phy_init_status, ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	u16 phy_id_high, phy_id_low;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	bool match = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	DEBUGFUNC("e1000_detect_gig_phy");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	if (hw->phy_id != 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
	/* Read the PHY ID Registers to identify which PHY is onboard. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
	ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
	hw->phy_id = (u32) (phy_id_high << 16);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	udelay(20);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	hw->phy_id |= (u32) (phy_id_low & PHY_REVISION_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	hw->phy_revision = (u32) phy_id_low & ~PHY_REVISION_MASK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	case e1000_82543:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
		if (hw->phy_id == M88E1000_E_PHY_ID)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
			match = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
		if (hw->phy_id == M88E1000_I_PHY_ID)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
			match = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
	case e1000_82540:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	case e1000_82545:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	case e1000_82546:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
		if (hw->phy_id == M88E1011_I_PHY_ID)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
			match = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
	case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
		if (hw->phy_id == IGP01E1000_I_PHY_ID)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
			match = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
		DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		return -E1000_ERR_CONFIG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
	phy_init_status = e1000_set_phy_type(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
	if ((match) && (phy_init_status == E1000_SUCCESS)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
		DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	return -E1000_ERR_PHY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
 * e1000_phy_reset_dsp - reset DSP
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
 * Resets the PHY's DSP
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	DEBUGFUNC("e1000_phy_reset_dsp");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
	do {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
		ret_val = e1000_write_phy_reg(hw, 29, 0x001d);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
		ret_val = e1000_write_phy_reg(hw, 30, 0x00c1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
		ret_val = e1000_write_phy_reg(hw, 30, 0x0000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		ret_val = E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
	} while (0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
 * e1000_phy_igp_get_info - get igp specific registers
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
 * @phy_info: PHY information structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
 * Get PHY information from various PHY registers for igp PHY only.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
				  struct e1000_phy_info *phy_info)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
	u16 phy_data, min_length, max_length, average;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
	e1000_rev_polarity polarity;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
	DEBUGFUNC("e1000_phy_igp_get_info");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
	/* The downshift status is checked only once, after link is established,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	 * and it stored in the hw->speed_downgraded parameter. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	phy_info->downshift = (e1000_downshift) hw->speed_downgraded;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	/* IGP01E1000 does not need to support it. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
	/* IGP01E1000 always correct polarity reversal */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
	phy_info->polarity_correction = e1000_polarity_reversal_enabled;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	/* Check polarity status */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	ret_val = e1000_check_polarity(hw, &polarity);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
	phy_info->cable_polarity = polarity;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	phy_info->mdix_mode =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
	    (e1000_auto_x_mode) ((phy_data & IGP01E1000_PSSR_MDIX) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
				 IGP01E1000_PSSR_MDIX_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
		/* Local/Remote Receiver Information are only valid at 1000 Mbps */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
		phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
		/* Get cable length */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
		ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
		/* Translate to old method */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		average = (max_length + min_length) / 2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		if (average <= e1000_igp_cable_length_50)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
			phy_info->cable_length = e1000_cable_length_50;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
		else if (average <= e1000_igp_cable_length_80)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
			phy_info->cable_length = e1000_cable_length_50_80;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
		else if (average <= e1000_igp_cable_length_110)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
			phy_info->cable_length = e1000_cable_length_80_110;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
		else if (average <= e1000_igp_cable_length_140)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
			phy_info->cable_length = e1000_cable_length_110_140;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
			phy_info->cable_length = e1000_cable_length_140;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
 * e1000_phy_m88_get_info - get m88 specific registers
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
 * @phy_info: PHY information structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
 * Get PHY information from various PHY registers for m88 PHY only.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
				  struct e1000_phy_info *phy_info)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	e1000_rev_polarity polarity;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
	DEBUGFUNC("e1000_phy_m88_get_info");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	/* The downshift status is checked only once, after link is established,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	 * and it stored in the hw->speed_downgraded parameter. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	phy_info->downshift = (e1000_downshift) hw->speed_downgraded;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	phy_info->extended_10bt_distance =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	    ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	     M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	    e1000_10bt_ext_dist_enable_lower :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	    e1000_10bt_ext_dist_enable_normal;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	phy_info->polarity_correction =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	    ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	     M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	    e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	/* Check polarity status */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	ret_val = e1000_check_polarity(hw, &polarity);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	phy_info->cable_polarity = polarity;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
	phy_info->mdix_mode =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	    (e1000_auto_x_mode) ((phy_data & M88E1000_PSSR_MDIX) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
				 M88E1000_PSSR_MDIX_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
		/* Cable Length Estimation and Local/Remote Receiver Information
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
		 * are only valid at 1000 Mbps.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		phy_info->cable_length =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
		    (e1000_cable_length) ((phy_data &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
					   M88E1000_PSSR_CABLE_LENGTH) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
					  M88E1000_PSSR_CABLE_LENGTH_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
		phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
 * e1000_phy_get_info - request phy info
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
 * @phy_info: PHY information structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
 * Get PHY information from various PHY registers
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
s32 e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
	DEBUGFUNC("e1000_phy_get_info");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
	phy_info->cable_length = e1000_cable_length_undefined;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
	phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	phy_info->cable_polarity = e1000_rev_polarity_undefined;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	phy_info->downshift = e1000_downshift_undefined;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
	phy_info->polarity_correction = e1000_polarity_reversal_undefined;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	phy_info->mdix_mode = e1000_auto_x_mode_undefined;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	phy_info->local_rx = e1000_1000t_rx_status_undefined;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	phy_info->remote_rx = e1000_1000t_rx_status_undefined;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
	if (hw->media_type != e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
		DEBUGOUT("PHY info is only valid for copper media\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
		return -E1000_ERR_CONFIG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	if ((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
		DEBUGOUT("PHY info is only valid if link is up\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
		return -E1000_ERR_CONFIG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	if (hw->phy_type == e1000_phy_igp)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
		return e1000_phy_igp_get_info(hw, phy_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
		return e1000_phy_m88_get_info(hw, phy_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
s32 e1000_validate_mdi_setting(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	DEBUGFUNC("e1000_validate_mdi_settings");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
	if (!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
		DEBUGOUT("Invalid MDI setting detected\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
		hw->mdix = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
		return -E1000_ERR_CONFIG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
 * e1000_init_eeprom_params - initialize sw eeprom vars
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
 * Sets up eeprom variables in the hw struct.  Must be called after mac_type
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
 * is configured.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
s32 e1000_init_eeprom_params(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	u32 eecd = er32(EECD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	s32 ret_val = E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	u16 eeprom_size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	DEBUGFUNC("e1000_init_eeprom_params");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
	case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
	case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	case e1000_82543:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
		eeprom->type = e1000_eeprom_microwire;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
		eeprom->word_size = 64;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
		eeprom->opcode_bits = 3;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
		eeprom->address_bits = 6;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
		eeprom->delay_usec = 50;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	case e1000_82540:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	case e1000_82545:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	case e1000_82546:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		eeprom->type = e1000_eeprom_microwire;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
		eeprom->opcode_bits = 3;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
		eeprom->delay_usec = 50;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
		if (eecd & E1000_EECD_SIZE) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
			eeprom->word_size = 256;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
			eeprom->address_bits = 8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
			eeprom->word_size = 64;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
			eeprom->address_bits = 6;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
		if (eecd & E1000_EECD_TYPE) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
			eeprom->type = e1000_eeprom_spi;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
			eeprom->opcode_bits = 8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
			eeprom->delay_usec = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
			if (eecd & E1000_EECD_ADDR_BITS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
				eeprom->page_size = 32;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
				eeprom->address_bits = 16;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
			} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
				eeprom->page_size = 8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
				eeprom->address_bits = 8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
			eeprom->type = e1000_eeprom_microwire;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
			eeprom->opcode_bits = 3;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
			eeprom->delay_usec = 50;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
			if (eecd & E1000_EECD_ADDR_BITS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
				eeprom->word_size = 256;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
				eeprom->address_bits = 8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
			} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
				eeprom->word_size = 64;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
				eeprom->address_bits = 6;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	if (eeprom->type == e1000_eeprom_spi) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
		/* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
		 * 32KB (incremented by powers of 2).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		/* Set to default value for initial eeprom read. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
		eeprom->word_size = 64;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
		ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
		eeprom_size =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
		    (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
		/* 256B eeprom size was not supported in earlier hardware, so we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
		 * bump eeprom_size up one to ensure that "1" (which maps to 256B)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
		 * is never the result used in the shifting logic below. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
		if (eeprom_size)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
			eeprom_size++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
		eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
 * e1000_raise_ee_clk - Raises the EEPROM's clock input.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
 * @eecd: EECD's current value
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
	/* Raise the clock input to the EEPROM (by setting the SK bit), and then
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
	 * wait <delay> microseconds.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	*eecd = *eecd | E1000_EECD_SK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
	ew32(EECD, *eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
	udelay(hw->eeprom.delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
 * e1000_lower_ee_clk - Lowers the EEPROM's clock input.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
 * @eecd: EECD's current value
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	 * wait 50 microseconds.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	*eecd = *eecd & ~E1000_EECD_SK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	ew32(EECD, *eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	udelay(hw->eeprom.delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
 * e1000_shift_out_ee_bits - Shift data bits out to the EEPROM.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
 * @data: data to send to the EEPROM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
 * @count: number of bits to shift out
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data, u16 count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	u32 eecd;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	u32 mask;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
	/* We need to shift "count" bits out to the EEPROM. So, value in the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	 * "data" parameter will be shifted out to the EEPROM one bit at a time.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
	 * In order to do this, "data" must be broken down into bits.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	mask = 0x01 << (count - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
	eecd = er32(EECD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	if (eeprom->type == e1000_eeprom_microwire) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
		eecd &= ~E1000_EECD_DO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
	} else if (eeprom->type == e1000_eeprom_spi) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
		eecd |= E1000_EECD_DO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	do {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		 * and then raising and then lowering the clock (the SK bit controls
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
		 * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
		 * by setting "DI" to "0" and then raising and then lowering the clock.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
		eecd &= ~E1000_EECD_DI;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		if (data & mask)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
			eecd |= E1000_EECD_DI;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
		udelay(eeprom->delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
		e1000_raise_ee_clk(hw, &eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
		e1000_lower_ee_clk(hw, &eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
		mask = mask >> 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	} while (mask);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	/* We leave the "DI" bit set to "0" when we leave this routine. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	eecd &= ~E1000_EECD_DI;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
	ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
 * e1000_shift_in_ee_bits - Shift data bits in from the EEPROM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
 * @count: number of bits to shift in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	u32 eecd;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	u32 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	u16 data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
	/* In order to read a register from the EEPROM, we need to shift 'count'
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	 * bits in from the EEPROM. Bits are "shifted in" by raising the clock
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	 * input to the EEPROM (setting the SK bit), and then reading the value of
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
	 * the "DO" bit.  During this "shifting in" process the "DI" bit should
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
	 * always be clear.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
	eecd = er32(EECD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
	data = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
	for (i = 0; i < count; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
		data = data << 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
		e1000_raise_ee_clk(hw, &eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
		eecd = er32(EECD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
		eecd &= ~(E1000_EECD_DI);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
		if (eecd & E1000_EECD_DO)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
			data |= 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
		e1000_lower_ee_clk(hw, &eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	return data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
 * e1000_acquire_eeprom - Prepares EEPROM for access
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
 * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
 * function should be called before issuing a command to the EEPROM.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
static s32 e1000_acquire_eeprom(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
	u32 eecd, i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
	DEBUGFUNC("e1000_acquire_eeprom");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
	eecd = er32(EECD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
	/* Request EEPROM Access */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
	if (hw->mac_type > e1000_82544) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
		eecd |= E1000_EECD_REQ;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		eecd = er32(EECD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
		while ((!(eecd & E1000_EECD_GNT)) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
		       (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
			i++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
			udelay(5);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
			eecd = er32(EECD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		if (!(eecd & E1000_EECD_GNT)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
			eecd &= ~E1000_EECD_REQ;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
			ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
			DEBUGOUT("Could not acquire EEPROM grant\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
			return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	/* Setup EEPROM for Read/Write */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
	if (eeprom->type == e1000_eeprom_microwire) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		/* Clear SK and DI */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
		/* Set CS */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
		eecd |= E1000_EECD_CS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
	} else if (eeprom->type == e1000_eeprom_spi) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
		/* Clear SK and CS */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
		udelay(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
 * e1000_standby_eeprom - Returns EEPROM to a "standby" state
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
static void e1000_standby_eeprom(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
	u32 eecd;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
	eecd = er32(EECD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	if (eeprom->type == e1000_eeprom_microwire) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
		udelay(eeprom->delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
		/* Clock high */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
		eecd |= E1000_EECD_SK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
		udelay(eeprom->delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
		/* Select EEPROM */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
		eecd |= E1000_EECD_CS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
		udelay(eeprom->delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
		/* Clock low */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
		eecd &= ~E1000_EECD_SK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
		udelay(eeprom->delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
	} else if (eeprom->type == e1000_eeprom_spi) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
		/* Toggle CS to flush commands */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
		eecd |= E1000_EECD_CS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
		udelay(eeprom->delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
		eecd &= ~E1000_EECD_CS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
		udelay(eeprom->delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
 * e1000_release_eeprom - drop chip select
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
 * Terminates a command by inverting the EEPROM's chip select pin
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
static void e1000_release_eeprom(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	u32 eecd;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	DEBUGFUNC("e1000_release_eeprom");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	eecd = er32(EECD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	if (hw->eeprom.type == e1000_eeprom_spi) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
		eecd |= E1000_EECD_CS;	/* Pull CS high */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
		eecd &= ~E1000_EECD_SK;	/* Lower SCK */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
		udelay(hw->eeprom.delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
	} else if (hw->eeprom.type == e1000_eeprom_microwire) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
		/* cleanup eeprom */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
		/* CS on Microwire is active-high */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
		/* Rising edge of clock */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
		eecd |= E1000_EECD_SK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
		udelay(hw->eeprom.delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
		/* Falling edge of clock */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
		eecd &= ~E1000_EECD_SK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
		udelay(hw->eeprom.delay_usec);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	/* Stop requesting EEPROM access */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	if (hw->mac_type > e1000_82544) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
		eecd &= ~E1000_EECD_REQ;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
		ew32(EECD, eecd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
 * e1000_spi_eeprom_ready - Reads a 16 bit word from the EEPROM.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	u16 retry_count = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	u8 spi_stat_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
	DEBUGFUNC("e1000_spi_eeprom_ready");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	/* Read "Status Register" repeatedly until the LSB is cleared.  The
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
	 * EEPROM will signal that the command has been completed by clearing
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	 * bit 0 of the internal status register.  If it's not cleared within
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
	 * 5 milliseconds, then error out.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	retry_count = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	do {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
		e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
					hw->eeprom.opcode_bits);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
		spi_stat_reg = (u8) e1000_shift_in_ee_bits(hw, 8);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
		if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
		udelay(5);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
		retry_count += 5;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
		e1000_standby_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
	} while (retry_count < EEPROM_MAX_RETRY_SPI);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
	/* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
	 * only 0-5mSec on 5V devices)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
	if (retry_count >= EEPROM_MAX_RETRY_SPI) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
		DEBUGOUT("SPI EEPROM Status error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
		return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
 * e1000_read_eeprom - Reads a 16 bit word from the EEPROM.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
 * @offset: offset of  word in the EEPROM to read
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
 * @data: word read from the EEPROM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
 * @words: number of words to read
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	s32 ret;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
	spin_lock(&e1000_eeprom_lock);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	ret = e1000_do_read_eeprom(hw, offset, words, data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
	spin_unlock(&e1000_eeprom_lock);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
	return ret;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
				u16 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
	u32 i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	DEBUGFUNC("e1000_read_eeprom");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
	/* If eeprom is not yet detected, do so now */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
	if (eeprom->word_size == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
		e1000_init_eeprom_params(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
	/* A check for invalid values:  offset too large, too many words, and not
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
	 * enough words.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
	if ((offset >= eeprom->word_size)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
	    || (words > eeprom->word_size - offset) || (words == 0)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
		DEBUGOUT2
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
		    ("\"words\" parameter out of bounds. Words = %d, size = %d\n",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
		     offset, eeprom->word_size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
		return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
	/* EEPROM's that don't use EERD to read require us to bit-bang the SPI
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
	 * directly. In this case, we need to acquire the EEPROM so that
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
	 * FW or other port software does not interrupt.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
	/* Prepare the EEPROM for bit-bang reading */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
	/* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
	 * acquired the EEPROM at this point, so any returns should release it */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
	if (eeprom->type == e1000_eeprom_spi) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
		u16 word_in;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
		u8 read_opcode = EEPROM_READ_OPCODE_SPI;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
		if (e1000_spi_eeprom_ready(hw)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
			e1000_release_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
			return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
		e1000_standby_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
		/* Some SPI eeproms use the 8th address bit embedded in the opcode */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
		if ((eeprom->address_bits == 8) && (offset >= 128))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
			read_opcode |= EEPROM_A8_OPCODE_SPI;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
		/* Send the READ command (opcode + addr)  */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
		e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
		e1000_shift_out_ee_bits(hw, (u16) (offset * 2),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
					eeprom->address_bits);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
		/* Read the data.  The address of the eeprom internally increments with
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
		 * each byte (spi) being read, saving on the overhead of eeprom setup
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
		 * and tear-down.  The address counter will roll over if reading beyond
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
		 * the size of the eeprom, thus allowing the entire memory to be read
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
		 * starting from any offset. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		for (i = 0; i < words; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
			word_in = e1000_shift_in_ee_bits(hw, 16);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
			data[i] = (word_in >> 8) | (word_in << 8);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	} else if (eeprom->type == e1000_eeprom_microwire) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
		for (i = 0; i < words; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
			/* Send the READ command (opcode + addr)  */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
			e1000_shift_out_ee_bits(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
						EEPROM_READ_OPCODE_MICROWIRE,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
						eeprom->opcode_bits);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
			e1000_shift_out_ee_bits(hw, (u16) (offset + i),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
						eeprom->address_bits);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
			/* Read the data.  For microwire, each word requires the overhead
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
			 * of eeprom setup and tear-down. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
			data[i] = e1000_shift_in_ee_bits(hw, 16);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
			e1000_standby_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
	/* End this read operation */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
	e1000_release_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
 * e1000_validate_eeprom_checksum - Verifies that the EEPROM has a valid checksum
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
 * Reads the first 64 16 bit words of the EEPROM and sums the values read.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
 * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
 * valid.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
	u16 checksum = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	u16 i, eeprom_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	DEBUGFUNC("e1000_validate_eeprom_checksum");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
		if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
			DEBUGOUT("EEPROM Read Error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
			return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
		checksum += eeprom_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
	if (checksum == (u16) EEPROM_SUM)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
	else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
		DEBUGOUT("EEPROM Checksum Invalid\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
 * e1000_update_eeprom_checksum - Calculates/writes the EEPROM checksum
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
 * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
 * Writes the difference to word offset 63 of the EEPROM.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
s32 e1000_update_eeprom_checksum(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
	u16 checksum = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	u16 i, eeprom_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
	DEBUGFUNC("e1000_update_eeprom_checksum");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
	for (i = 0; i < EEPROM_CHECKSUM_REG; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
		if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
			DEBUGOUT("EEPROM Read Error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
			return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
		checksum += eeprom_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
	checksum = (u16) EEPROM_SUM - checksum;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
	if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
		DEBUGOUT("EEPROM Write Error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
		return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
 * e1000_write_eeprom - write words to the different EEPROM types.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
 * @offset: offset within the EEPROM to be written to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
 * @words: number of words to write
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
 * @data: 16 bit word to be written to the EEPROM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
 * If e1000_update_eeprom_checksum is not called after this function, the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
 * EEPROM will most likely contain an invalid checksum.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
	s32 ret;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	spin_lock(&e1000_eeprom_lock);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
	ret = e1000_do_write_eeprom(hw, offset, words, data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
	spin_unlock(&e1000_eeprom_lock);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
	return ret;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
				 u16 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	s32 status = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
	DEBUGFUNC("e1000_write_eeprom");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
	/* If eeprom is not yet detected, do so now */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
	if (eeprom->word_size == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		e1000_init_eeprom_params(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
	/* A check for invalid values:  offset too large, too many words, and not
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
	 * enough words.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
	if ((offset >= eeprom->word_size)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
	    || (words > eeprom->word_size - offset) || (words == 0)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		DEBUGOUT("\"words\" parameter out of bounds\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
		return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	/* Prepare the EEPROM for writing  */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
	if (eeprom->type == e1000_eeprom_microwire) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
		status = e1000_write_eeprom_microwire(hw, offset, words, data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
		status = e1000_write_eeprom_spi(hw, offset, words, data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
	/* Done with writing */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	e1000_release_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
	return status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
 * e1000_write_eeprom_spi - Writes a 16 bit word to a given offset in an SPI EEPROM.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
 * @offset: offset within the EEPROM to be written to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
 * @words: number of words to write
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
 * @data: pointer to array of 8 bit words to be written to the EEPROM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset, u16 words,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
				  u16 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	u16 widx = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
	DEBUGFUNC("e1000_write_eeprom_spi");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
	while (widx < words) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
		u8 write_opcode = EEPROM_WRITE_OPCODE_SPI;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
		if (e1000_spi_eeprom_ready(hw))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
			return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
		e1000_standby_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
		/*  Send the WRITE ENABLE command (8 bit opcode )  */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
		e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
					eeprom->opcode_bits);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
		e1000_standby_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
		/* Some SPI eeproms use the 8th address bit embedded in the opcode */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
		if ((eeprom->address_bits == 8) && (offset >= 128))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
			write_opcode |= EEPROM_A8_OPCODE_SPI;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
		/* Send the Write command (8-bit opcode + addr) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
		e1000_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
		e1000_shift_out_ee_bits(hw, (u16) ((offset + widx) * 2),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
					eeprom->address_bits);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		/* Send the data */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
		/* Loop to allow for up to whole page write (32 bytes) of eeprom */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
		while (widx < words) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
			u16 word_out = data[widx];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
			word_out = (word_out >> 8) | (word_out << 8);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
			e1000_shift_out_ee_bits(hw, word_out, 16);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
			widx++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
			/* Some larger eeprom sizes are capable of a 32-byte PAGE WRITE
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
			 * operation, while the smaller eeproms are capable of an 8-byte
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
			 * PAGE WRITE operation.  Break the inner loop to pass new address
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
			if ((((offset + widx) * 2) % eeprom->page_size) == 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
				e1000_standby_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
 * e1000_write_eeprom_microwire - Writes a 16 bit word to a given offset in a Microwire EEPROM.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
 * @offset: offset within the EEPROM to be written to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
 * @words: number of words to write
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
 * @data: pointer to array of 8 bit words to be written to the EEPROM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
					u16 words, u16 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
	u32 eecd;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
	u16 words_written = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
	u16 i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
	DEBUGFUNC("e1000_write_eeprom_microwire");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
	/* Send the write enable command to the EEPROM (3-bit opcode plus
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
	 * 6/8-bit dummy address beginning with 11).  It's less work to include
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
	 * the 11 of the dummy address as part of the opcode than it is to shift
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
	 * it over the correct number of bits for the address.  This puts the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
	 * EEPROM into write/erase mode.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
	e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
				(u16) (eeprom->opcode_bits + 2));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
	/* Prepare the EEPROM */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
	e1000_standby_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	while (words_written < words) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
		/* Send the Write command (3-bit opcode + addr) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
		e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
					eeprom->opcode_bits);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
		e1000_shift_out_ee_bits(hw, (u16) (offset + words_written),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
					eeprom->address_bits);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
		/* Send the data */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
		e1000_shift_out_ee_bits(hw, data[words_written], 16);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
		/* Toggle the CS line.  This in effect tells the EEPROM to execute
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
		 * the previous command.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
		e1000_standby_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
		/* Read DO repeatedly until it is high (equal to '1').  The EEPROM will
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
		 * signal that the command has been completed by raising the DO signal.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
		 * If DO does not go high in 10 milliseconds, then error out.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
		for (i = 0; i < 200; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
			eecd = er32(EECD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
			if (eecd & E1000_EECD_DO)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
			udelay(50);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
		if (i == 200) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
			DEBUGOUT("EEPROM Write did not complete\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
			return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
		/* Recover from write */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		e1000_standby_eeprom(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
		words_written++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
	/* Send the write disable command to the EEPROM (3-bit opcode plus
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
	 * 6/8-bit dummy address beginning with 10).  It's less work to include
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
	 * the 10 of the dummy address as part of the opcode than it is to shift
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
	 * it over the correct number of bits for the address.  This takes the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
	 * EEPROM out of write/erase mode.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
	e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
				(u16) (eeprom->opcode_bits + 2));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
 * e1000_read_mac_addr - read the adapters MAC from eeprom
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
 * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
 * second function of dual function devices
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
s32 e1000_read_mac_addr(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	u16 offset;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	u16 eeprom_data, i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	DEBUGFUNC("e1000_read_mac_addr");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
		offset = i >> 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
		if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
			DEBUGOUT("EEPROM Read Error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
			return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
		hw->perm_mac_addr[i] = (u8) (eeprom_data & 0x00FF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
		hw->perm_mac_addr[i + 1] = (u8) (eeprom_data >> 8);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
	case e1000_82546:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
			hw->perm_mac_addr[5] ^= 0x01;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
	for (i = 0; i < NODE_ADDRESS_SIZE; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
		hw->mac_addr[i] = hw->perm_mac_addr[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
 * e1000_init_rx_addrs - Initializes receive address filters.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
 * Places the MAC address in receive address register 0 and clears the rest
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
 * of the receive address registers. Clears the multicast table. Assumes
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
 * the receiver is in reset when the routine is called.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
static void e1000_init_rx_addrs(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
	u32 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
	u32 rar_num;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
	DEBUGFUNC("e1000_init_rx_addrs");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
	/* Setup the receive address. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
	DEBUGOUT("Programming MAC Address into RAR[0]\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
	e1000_rar_set(hw, hw->mac_addr, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
	rar_num = E1000_RAR_ENTRIES;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
	/* Zero out the other 15 receive addresses. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
	DEBUGOUT("Clearing RAR[1-15]\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
	for (i = 1; i < rar_num; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
		E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
 * e1000_hash_mc_addr - Hashes an address to determine its location in the multicast table
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
 * @mc_addr: the multicast address to hash
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
	u32 hash_value = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
	/* The portion of the address that is used for the hash table is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
	 * determined by the mc_filter_type setting.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
	switch (hw->mc_filter_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
		/* [0] [1] [2] [3] [4] [5]
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
		 * 01  AA  00  12  34  56
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
		 * LSB                 MSB
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
	case 0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
		/* [47:36] i.e. 0x563 for above example address */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		hash_value = ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
	case 1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
		/* [46:35] i.e. 0xAC6 for above example address */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
		hash_value = ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
	case 2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
		/* [45:34] i.e. 0x5D8 for above example address */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
		hash_value = ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
	case 3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
		/* [43:32] i.e. 0x634 for above example address */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
		hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
	hash_value &= 0xFFF;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
	return hash_value;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
 * e1000_rar_set - Puts an ethernet address into a receive address register.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
 * @addr: Address to put into receive address register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
 * @index: Receive address register to write
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
	u32 rar_low, rar_high;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
	/* HW expects these in little endian so we reverse the byte order
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
	 * from network order (big endian) to little endian
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
	rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
		   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
	/* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
	 * unit hang.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
	 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
	 * Description:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
	 * If there are any Rx frames queued up or otherwise present in the HW
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
	 * before RSS is enabled, and then we enable RSS, the HW Rx unit will
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
	 * hang.  To work around this issue, we have to disable receives and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
	 * flush out all Rx frames before we enable RSS. To do so, we modify we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
	 * redirect all Rx traffic to manageability and then reset the HW.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
	 * This flushes away Rx frames, and (since the redirections to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
	 * manageability persists across resets) keeps new ones from coming in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
	 * while we work.  Then, we clear the Address Valid AV bit for all MAC
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
	 * addresses and undo the re-direction to manageability.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
	 * Now, frames are coming in again, but the MAC won't accept them, so
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
	 * far so good.  We now proceed to initialize RSS (if necessary) and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	 * configure the Rx unit.  Last, we re-enable the AV bits and continue
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	 * on our merry way.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
		/* Indicate to hardware the Address is Valid. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
		rar_high |= E1000_RAH_AV;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
	E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
	E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
 * e1000_write_vfta - Writes a value to the specified offset in the VLAN filter table.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
 * @offset: Offset in VLAN filer table to write
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
 * @value: Value to write into VLAN filter table
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
	u32 temp;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
	if ((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
		temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
		E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
 * e1000_clear_vfta - Clears the VLAN filer table
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
static void e1000_clear_vfta(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	u32 offset;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
	u32 vfta_value = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
	u32 vfta_offset = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	u32 vfta_bit_in_reg = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
		/* If the offset we want to clear is the same offset of the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
		 * manageability VLAN ID, then clear all bits except that of the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
		 * manageability unit */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
		vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
		E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
static s32 e1000_id_led_init(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
	u32 ledctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
	const u32 ledctl_mask = 0x000000FF;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
	u16 eeprom_data, i, temp;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
	const u16 led_mask = 0x0F;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
	DEBUGFUNC("e1000_id_led_init");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
	if (hw->mac_type < e1000_82540) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
		/* Nothing to do */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
	ledctl = er32(LEDCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
	hw->ledctl_default = ledctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
	hw->ledctl_mode1 = hw->ledctl_default;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
	hw->ledctl_mode2 = hw->ledctl_default;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
	if (e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
		DEBUGOUT("EEPROM Read Error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
		return -E1000_ERR_EEPROM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
	if ((eeprom_data == ID_LED_RESERVED_0000) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	    (eeprom_data == ID_LED_RESERVED_FFFF)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
		eeprom_data = ID_LED_DEFAULT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	for (i = 0; i < 4; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		temp = (eeprom_data >> (i << 2)) & led_mask;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
		switch (temp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
		case ID_LED_ON1_DEF2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
		case ID_LED_ON1_ON2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
		case ID_LED_ON1_OFF2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
			hw->ledctl_mode1 |= ledctl_on << (i << 3);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
		case ID_LED_OFF1_DEF2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
		case ID_LED_OFF1_ON2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
		case ID_LED_OFF1_OFF2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
			hw->ledctl_mode1 |= ledctl_off << (i << 3);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
			/* Do nothing */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
		switch (temp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
		case ID_LED_DEF1_ON2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
		case ID_LED_ON1_ON2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
		case ID_LED_OFF1_ON2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
			hw->ledctl_mode2 |= ledctl_on << (i << 3);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
		case ID_LED_DEF1_OFF2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
		case ID_LED_ON1_OFF2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		case ID_LED_OFF1_OFF2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
			hw->ledctl_mode2 |= ledctl_off << (i << 3);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
			/* Do nothing */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
 * e1000_setup_led
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
 * Prepares SW controlable LED for use and saves the current state of the LED.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
s32 e1000_setup_led(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
	u32 ledctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
	s32 ret_val = E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	DEBUGFUNC("e1000_setup_led");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
	case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
	case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
	case e1000_82543:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
		/* No setup necessary */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
	case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
	case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
	case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
	case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
		/* Turn off PHY Smart Power Down (if enabled) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
					     &hw->phy_spd_default);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
					      (u16) (hw->phy_spd_default &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
						     ~IGP01E1000_GMII_SPD));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
		/* Fall Through */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
		if (hw->media_type == e1000_media_type_fiber) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
			ledctl = er32(LEDCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
			/* Save current LEDCTL settings */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
			hw->ledctl_default = ledctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
			/* Turn off LED0 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
			ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
				    E1000_LEDCTL_LED0_BLINK |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
				    E1000_LEDCTL_LED0_MODE_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
			ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
				   E1000_LEDCTL_LED0_MODE_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
			ew32(LEDCTL, ledctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
		} else if (hw->media_type == e1000_media_type_copper)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
			ew32(LEDCTL, hw->ledctl_mode1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
 * e1000_cleanup_led - Restores the saved state of the SW controlable LED.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
s32 e1000_cleanup_led(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	s32 ret_val = E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
	DEBUGFUNC("e1000_cleanup_led");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
	case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
	case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
	case e1000_82543:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
		/* No cleanup necessary */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
	case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
	case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
	case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
		/* Turn on PHY Smart Power Down (if previously enabled) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
					      hw->phy_spd_default);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		/* Fall Through */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
		/* Restore LEDCTL settings */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
		ew32(LEDCTL, hw->ledctl_default);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
 * e1000_led_on - Turns on the software controllable LED
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
s32 e1000_led_on(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
	u32 ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
	DEBUGFUNC("e1000_led_on");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
	case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	case e1000_82543:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
		/* Set SW Defineable Pin 0 to turn on the LED */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
		ctrl |= E1000_CTRL_SWDPIN0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
		ctrl |= E1000_CTRL_SWDPIO0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
		if (hw->media_type == e1000_media_type_fiber) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
			/* Set SW Defineable Pin 0 to turn on the LED */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
			ctrl |= E1000_CTRL_SWDPIN0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
			ctrl |= E1000_CTRL_SWDPIO0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
			/* Clear SW Defineable Pin 0 to turn on the LED */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
			ctrl &= ~E1000_CTRL_SWDPIN0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
			ctrl |= E1000_CTRL_SWDPIO0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
		if (hw->media_type == e1000_media_type_fiber) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
			/* Clear SW Defineable Pin 0 to turn on the LED */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
			ctrl &= ~E1000_CTRL_SWDPIN0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
			ctrl |= E1000_CTRL_SWDPIO0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
		} else if (hw->media_type == e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
			ew32(LEDCTL, hw->ledctl_mode2);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
			return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
 * e1000_led_off - Turns off the software controllable LED
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
s32 e1000_led_off(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
	u32 ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	DEBUGFUNC("e1000_led_off");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
	case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
	case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
	case e1000_82543:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
		/* Clear SW Defineable Pin 0 to turn off the LED */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
		ctrl &= ~E1000_CTRL_SWDPIN0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
		ctrl |= E1000_CTRL_SWDPIO0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
		if (hw->media_type == e1000_media_type_fiber) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
			/* Clear SW Defineable Pin 0 to turn off the LED */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
			ctrl &= ~E1000_CTRL_SWDPIN0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
			ctrl |= E1000_CTRL_SWDPIO0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
			/* Set SW Defineable Pin 0 to turn off the LED */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
			ctrl |= E1000_CTRL_SWDPIN0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
			ctrl |= E1000_CTRL_SWDPIO0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
		if (hw->media_type == e1000_media_type_fiber) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
			/* Set SW Defineable Pin 0 to turn off the LED */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
			ctrl |= E1000_CTRL_SWDPIN0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
			ctrl |= E1000_CTRL_SWDPIO0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
		} else if (hw->media_type == e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
			ew32(LEDCTL, hw->ledctl_mode1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
			return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
 * e1000_clear_hw_cntrs - Clears all hardware statistics counters.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
static void e1000_clear_hw_cntrs(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	volatile u32 temp;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	temp = er32(CRCERRS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	temp = er32(SYMERRS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	temp = er32(MPC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	temp = er32(SCC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	temp = er32(ECOL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
	temp = er32(MCC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
	temp = er32(LATECOL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
	temp = er32(COLC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
	temp = er32(DC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
	temp = er32(SEC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
	temp = er32(RLEC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
	temp = er32(XONRXC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
	temp = er32(XONTXC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	temp = er32(XOFFRXC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
	temp = er32(XOFFTXC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
	temp = er32(FCRUC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
	temp = er32(PRC64);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	temp = er32(PRC127);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
	temp = er32(PRC255);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
	temp = er32(PRC511);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
	temp = er32(PRC1023);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	temp = er32(PRC1522);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
	temp = er32(GPRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
	temp = er32(BPRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	temp = er32(MPRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
	temp = er32(GPTC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
	temp = er32(GORCL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	temp = er32(GORCH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
	temp = er32(GOTCL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
	temp = er32(GOTCH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	temp = er32(RNBC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
	temp = er32(RUC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
	temp = er32(RFC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	temp = er32(ROC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
	temp = er32(RJC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
	temp = er32(TORL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	temp = er32(TORH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	temp = er32(TOTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	temp = er32(TOTH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
	temp = er32(TPR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	temp = er32(TPT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	temp = er32(PTC64);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	temp = er32(PTC127);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	temp = er32(PTC255);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
	temp = er32(PTC511);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	temp = er32(PTC1023);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
	temp = er32(PTC1522);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
	temp = er32(MPTC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
	temp = er32(BPTC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	if (hw->mac_type < e1000_82543)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	temp = er32(ALGNERRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	temp = er32(RXERRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	temp = er32(TNCRS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	temp = er32(CEXTERR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
	temp = er32(TSCTC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	temp = er32(TSCTFC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
	if (hw->mac_type <= e1000_82544)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	temp = er32(MGTPRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	temp = er32(MGTPDC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	temp = er32(MGTPTC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
 * e1000_reset_adaptive - Resets Adaptive IFS to its default state.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
 * Call this after e1000_init_hw. You may override the IFS defaults by setting
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
 * hw->ifs_params_forced to true. However, you must initialize hw->
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
 * current_ifs_val, ifs_min_val, ifs_max_val, ifs_step_size, and ifs_ratio
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
 * before calling this function.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
void e1000_reset_adaptive(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
	DEBUGFUNC("e1000_reset_adaptive");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	if (hw->adaptive_ifs) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
		if (!hw->ifs_params_forced) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
			hw->current_ifs_val = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
			hw->ifs_min_val = IFS_MIN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
			hw->ifs_max_val = IFS_MAX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
			hw->ifs_step_size = IFS_STEP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
			hw->ifs_ratio = IFS_RATIO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		hw->in_ifs_mode = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
		ew32(AIT, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
		DEBUGOUT("Not in Adaptive IFS mode!\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
 * e1000_update_adaptive - update adaptive IFS
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
 * @tx_packets: Number of transmits since last callback
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
 * @total_collisions: Number of collisions since last callback
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
 * Called during the callback/watchdog routine to update IFS value based on
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
 * the ratio of transmits to collisions.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
void e1000_update_adaptive(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
	DEBUGFUNC("e1000_update_adaptive");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
	if (hw->adaptive_ifs) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
		if ((hw->collision_delta *hw->ifs_ratio) > hw->tx_packet_delta) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
			if (hw->tx_packet_delta > MIN_NUM_XMITS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
				hw->in_ifs_mode = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
				if (hw->current_ifs_val < hw->ifs_max_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
					if (hw->current_ifs_val == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
						hw->current_ifs_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
						    hw->ifs_min_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
					else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
						hw->current_ifs_val +=
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
						    hw->ifs_step_size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
					ew32(AIT, hw->current_ifs_val);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
				}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
			if (hw->in_ifs_mode
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
			    && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
				hw->current_ifs_val = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
				hw->in_ifs_mode = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
				ew32(AIT, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
		DEBUGOUT("Not in Adaptive IFS mode!\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
 * e1000_tbi_adjust_stats
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
 * @frame_len: The length of the frame in question
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
 * @mac_addr: The Ethernet destination address of the frame in question
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
 * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
			    u32 frame_len, u8 *mac_addr)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
	u64 carry_bit;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	/* First adjust the frame length. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
	frame_len--;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
	/* We need to adjust the statistics counters, since the hardware
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
	 * counters overcount this packet as a CRC error and undercount
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
	 * the packet as a good packet
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
	/* This packet should not be counted as a CRC error.    */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	stats->crcerrs--;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
	/* This packet does count as a Good Packet Received.    */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	stats->gprc++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	/* Adjust the Good Octets received counters             */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	carry_bit = 0x80000000 & stats->gorcl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	stats->gorcl += frame_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	/* If the high bit of Gorcl (the low 32 bits of the Good Octets
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	 * Received Count) was one before the addition,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	 * AND it is zero after, then we lost the carry out,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
	 * need to add one to Gorch (Good Octets Received Count High).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
	 * This could be simplified if all environments supported
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	 * 64-bit integers.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
	if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
		stats->gorch++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
	/* Is this a broadcast or multicast?  Check broadcast first,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
	 * since the test for a multicast frame will test positive on
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
	 * a broadcast frame.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
	if ((mac_addr[0] == (u8) 0xff) && (mac_addr[1] == (u8) 0xff))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
		/* Broadcast packet */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
		stats->bprc++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
	else if (*mac_addr & 0x01)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
		/* Multicast packet */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
		stats->mprc++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	if (frame_len == hw->max_frame_size) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
		/* In this case, the hardware has overcounted the number of
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
		 * oversize frames.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
		if (stats->roc > 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
			stats->roc--;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
	/* Adjust the bin counters when the extra byte put the frame in the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	 * wrong bin. Remember that the frame_len was adjusted above.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	if (frame_len == 64) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
		stats->prc64++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
		stats->prc127--;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	} else if (frame_len == 127) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
		stats->prc127++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
		stats->prc255--;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	} else if (frame_len == 255) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
		stats->prc255++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
		stats->prc511--;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
	} else if (frame_len == 511) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
		stats->prc511++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
		stats->prc1023--;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
	} else if (frame_len == 1023) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
		stats->prc1023++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
		stats->prc1522--;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
	} else if (frame_len == 1522) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
		stats->prc1522++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
 * e1000_get_bus_info
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
 * Gets the current PCI bus type, speed, and width of the hardware
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
void e1000_get_bus_info(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	u32 status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
	case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
		hw->bus_type = e1000_bus_type_pci;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
		hw->bus_speed = e1000_bus_speed_unknown;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
		hw->bus_width = e1000_bus_width_unknown;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
		status = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
		hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
		    e1000_bus_type_pcix : e1000_bus_type_pci;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
		if (hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
			hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
			    e1000_bus_speed_66 : e1000_bus_speed_120;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
		} else if (hw->bus_type == e1000_bus_type_pci) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
			hw->bus_speed = (status & E1000_STATUS_PCI66) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
			    e1000_bus_speed_66 : e1000_bus_speed_33;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
			switch (status & E1000_STATUS_PCIX_SPEED) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
			case E1000_STATUS_PCIX_SPEED_66:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
				hw->bus_speed = e1000_bus_speed_66;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
			case E1000_STATUS_PCIX_SPEED_100:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
				hw->bus_speed = e1000_bus_speed_100;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
			case E1000_STATUS_PCIX_SPEED_133:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
				hw->bus_speed = e1000_bus_speed_133;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
			default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
				hw->bus_speed = e1000_bus_speed_reserved;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
		hw->bus_width = (status & E1000_STATUS_BUS64) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
		    e1000_bus_width_64 : e1000_bus_width_32;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
 * e1000_write_reg_io
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
 * @offset: offset to write to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
 * @value: value to write
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
 * Writes a value to one of the devices registers using port I/O (as opposed to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
 * memory mapped I/O). Only 82544 and newer devices support port I/O.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
	unsigned long io_addr = hw->io_base;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
	unsigned long io_data = hw->io_base + 4;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
	e1000_io_write(hw, io_addr, offset);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	e1000_io_write(hw, io_data, value);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
 * e1000_get_cable_length - Estimates the cable length.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
 * @min_length: The estimated minimum length
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
 * @max_length: The estimated maximum length
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
 * returns: - E1000_ERR_XXX
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
 *            E1000_SUCCESS
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
 * This function always returns a ranged length (minimum & maximum).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
 * So for M88 phy's, this function interprets the one value returned from the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
 * register to the minimum and maximum range.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
 * For IGP phy's, the function calculates the range by the AGC registers.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
				  u16 *max_length)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
	u16 agc_value = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
	u16 i, phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	u16 cable_length;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
	DEBUGFUNC("e1000_get_cable_length");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
	*min_length = *max_length = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
	/* Use old method for Phy older than IGP */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
	if (hw->phy_type == e1000_phy_m88) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
					     &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
		cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
		    M88E1000_PSSR_CABLE_LENGTH_SHIFT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
		/* Convert the enum value to ranged values */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
		switch (cable_length) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
		case e1000_cable_length_50:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
			*min_length = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
			*max_length = e1000_igp_cable_length_50;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
		case e1000_cable_length_50_80:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
			*min_length = e1000_igp_cable_length_50;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
			*max_length = e1000_igp_cable_length_80;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
		case e1000_cable_length_80_110:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
			*min_length = e1000_igp_cable_length_80;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
			*max_length = e1000_igp_cable_length_110;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
		case e1000_cable_length_110_140:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
			*min_length = e1000_igp_cable_length_110;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
			*max_length = e1000_igp_cable_length_140;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
		case e1000_cable_length_140:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
			*min_length = e1000_igp_cable_length_140;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
			*max_length = e1000_igp_cable_length_170;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
			return -E1000_ERR_PHY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
	} else if (hw->phy_type == e1000_phy_igp) {	/* For IGP PHY */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
		u16 cur_agc_value;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
		u16 min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
		u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
		    { IGP01E1000_PHY_AGC_A,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
			IGP01E1000_PHY_AGC_B,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
			IGP01E1000_PHY_AGC_C,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
			IGP01E1000_PHY_AGC_D
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
		};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
		/* Read the AGC registers for all channels */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
		for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
			    e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
			cur_agc_value = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
			/* Value bound check. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
			if ((cur_agc_value >=
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
			     IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
			    || (cur_agc_value == 0))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
				return -E1000_ERR_PHY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
			agc_value += cur_agc_value;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
			/* Update minimal AGC value. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
			if (min_agc_value > cur_agc_value)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
				min_agc_value = cur_agc_value;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
		/* Remove the minimal AGC result for length < 50m */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
		if (agc_value <
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
		    IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
			agc_value -= min_agc_value;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
			/* Get the average length of the remaining 3 channels */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
			agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
			/* Get the average length of all the 4 channels. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
			agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
		/* Set the range of the calculated length. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
		*min_length = ((e1000_igp_cable_length_table[agc_value] -
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
				IGP01E1000_AGC_RANGE) > 0) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
		    (e1000_igp_cable_length_table[agc_value] -
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
		     IGP01E1000_AGC_RANGE) : 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
		*max_length = e1000_igp_cable_length_table[agc_value] +
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
		    IGP01E1000_AGC_RANGE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
 * e1000_check_polarity - Check the cable polarity
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
 * @polarity: output parameter : 0 - Polarity is not reversed
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
 *                               1 - Polarity is reversed.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
 * returns: - E1000_ERR_XXX
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
 *            E1000_SUCCESS
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
 * For phy's older than IGP, this function simply reads the polarity bit in the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
 * Phy Status register.  For IGP phy's, this bit is valid only if link speed is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
 * 10 Mbps.  If the link speed is 100 Mbps there is no polarity so this bit will
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
 * return 0.  If the link speed is 1000 Mbps the polarity status is in the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
 * IGP01E1000_PHY_PCS_INIT_REG.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
static s32 e1000_check_polarity(struct e1000_hw *hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
				e1000_rev_polarity *polarity)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
	DEBUGFUNC("e1000_check_polarity");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
	if (hw->phy_type == e1000_phy_m88) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
		/* return the Polarity bit in the Status register. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
					     &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
		*polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
			     M88E1000_PSSR_REV_POLARITY_SHIFT) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
		    e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
	} else if (hw->phy_type == e1000_phy_igp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
		/* Read the Status register to check the speed */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
					     &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
		/* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
		 * find the polarity status */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
		if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
		    IGP01E1000_PSSR_SPEED_1000MBPS) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
			/* Read the GIG initialization PCS register (0x00B4) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
					       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
			/* Check the polarity bits */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
			*polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
			    e1000_rev_polarity_reversed :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
			    e1000_rev_polarity_normal;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
			/* For 10 Mbps, read the polarity bit in the status register. (for
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
			 * 100 Mbps this bit is always 0) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
			*polarity =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
			    (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
			    e1000_rev_polarity_reversed :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
			    e1000_rev_polarity_normal;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
 * e1000_check_downshift - Check if Downshift occurred
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
 * @downshift: output parameter : 0 - No Downshift occurred.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
 *                                1 - Downshift occurred.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
 * returns: - E1000_ERR_XXX
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
 *            E1000_SUCCESS
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
 * For phy's older than IGP, this function reads the Downshift bit in the Phy
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
 * Specific Status register.  For IGP phy's, it reads the Downgrade bit in the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
 * Link Health register.  In IGP this bit is latched high, so the driver must
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
 * read it immediately after link is established.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
static s32 e1000_check_downshift(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
	DEBUGFUNC("e1000_check_downshift");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
	if (hw->phy_type == e1000_phy_igp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
					     &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
		hw->speed_downgraded =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
		    (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
	} else if (hw->phy_type == e1000_phy_m88) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
					     &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
		hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
		    M88E1000_PSSR_DOWNSHIFT_SHIFT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
 * e1000_config_dsp_after_link_change
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
 * @link_up: was link up at the time this was called
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
 *            E1000_SUCCESS at any other case.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
 * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
 * gigabit link is achieved to improve link quality.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw, bool link_up)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
	u16 phy_data, phy_saved_data, speed, duplex, i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
	u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
	    { IGP01E1000_PHY_AGC_PARAM_A,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
		IGP01E1000_PHY_AGC_PARAM_B,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
		IGP01E1000_PHY_AGC_PARAM_C,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
		IGP01E1000_PHY_AGC_PARAM_D
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
	};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
	u16 min_length, max_length;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
	DEBUGFUNC("e1000_config_dsp_after_link_change");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
	if (hw->phy_type != e1000_phy_igp)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
	if (link_up) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
		ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
			DEBUGOUT("Error getting link speed and duplex\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
		if (speed == SPEED_1000) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
			    e1000_get_cable_length(hw, &min_length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
						   &max_length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
			if ((hw->dsp_config_state == e1000_dsp_config_enabled)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
			    && min_length >= e1000_igp_cable_length_50) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
				for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
					ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
					    e1000_read_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
							       dsp_reg_array[i],
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
							       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
					if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
						return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
					phy_data &=
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
					    ~IGP01E1000_PHY_EDAC_MU_INDEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
					ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
					    e1000_write_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
								dsp_reg_array
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
								[i], phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
					if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
						return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
				}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
				hw->dsp_config_state =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
				    e1000_dsp_config_activated;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
			if ((hw->ffe_config_state == e1000_ffe_config_enabled)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
			    && (min_length < e1000_igp_cable_length_50)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
				u16 ffe_idle_err_timeout =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
				    FFE_IDLE_ERR_COUNT_TIMEOUT_20;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
				u32 idle_errs = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
				/* clear previous idle error counts */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
				ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
				    e1000_read_phy_reg(hw, PHY_1000T_STATUS,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
						       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
				if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
					return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
				for (i = 0; i < ffe_idle_err_timeout; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
					udelay(1000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
					ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
					    e1000_read_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
							       PHY_1000T_STATUS,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
							       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
					if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
						return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
					idle_errs +=
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
					    (phy_data &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
					     SR_1000T_IDLE_ERROR_CNT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
					if (idle_errs >
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
					    SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
					{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
						hw->ffe_config_state =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
						    e1000_ffe_config_active;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
						ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
						    e1000_write_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
									IGP01E1000_PHY_DSP_FFE,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
									IGP01E1000_PHY_DSP_FFE_CM_CP);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
						if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
							return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
						break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
					}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
					if (idle_errs)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
						ffe_idle_err_timeout =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
						    FFE_IDLE_ERR_COUNT_TIMEOUT_100;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
				}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
		if (hw->dsp_config_state == e1000_dsp_config_activated) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
			/* Save off the current value of register 0x2F5B to be restored at
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
			 * the end of the routines. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
			    e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
			/* Disable the PHY transmitter */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
			ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
			mdelay(20);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
			ret_val = e1000_write_phy_reg(hw, 0x0000,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
						      IGP01E1000_IEEE_FORCE_GIGA);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
			for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
				ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
				    e1000_read_phy_reg(hw, dsp_reg_array[i],
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
						       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
				if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
					return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
				phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
				phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
				ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
				    e1000_write_phy_reg(hw, dsp_reg_array[i],
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
							phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
				if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
					return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
			ret_val = e1000_write_phy_reg(hw, 0x0000,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
						      IGP01E1000_IEEE_RESTART_AUTONEG);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
			mdelay(20);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
			/* Now enable the transmitter */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
			    e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
			hw->dsp_config_state = e1000_dsp_config_enabled;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
		if (hw->ffe_config_state == e1000_ffe_config_active) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
			/* Save off the current value of register 0x2F5B to be restored at
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
			 * the end of the routines. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
			    e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
			/* Disable the PHY transmitter */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
			ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
			mdelay(20);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
			ret_val = e1000_write_phy_reg(hw, 0x0000,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
						      IGP01E1000_IEEE_FORCE_GIGA);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
						IGP01E1000_PHY_DSP_FFE_DEFAULT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
			ret_val = e1000_write_phy_reg(hw, 0x0000,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
						      IGP01E1000_IEEE_RESTART_AUTONEG);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
			mdelay(20);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
			/* Now enable the transmitter */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
			    e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
			hw->ffe_config_state = e1000_ffe_config_enabled;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
 * e1000_set_phy_mode - Set PHY to class A mode
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
 * Assumes the following operations will follow to enable the new class mode.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
 *  1. Do a PHY soft reset
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
 *  2. Restart auto-negotiation or force link.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
static s32 e1000_set_phy_mode(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
	u16 eeprom_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
	DEBUGFUNC("e1000_set_phy_mode");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
	if ((hw->mac_type == e1000_82545_rev_3) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
	    (hw->media_type == e1000_media_type_copper)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
		    e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
				      &eeprom_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
		if (ret_val) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
		if ((eeprom_data != EEPROM_RESERVED_WORD) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
		    (eeprom_data & EEPROM_PHY_CLASS_A)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
			    e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
						0x000B);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
			    e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
						0x8104);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
			hw->phy_reset_disable = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
 * e1000_set_d3_lplu_state - set d3 link power state
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
 * @active: true to enable lplu false to disable lplu.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
 * This function sets the lplu state according to the active flag.  When
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
 * activating lplu this function also disables smart speed and vise versa.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
 * lplu will not be activated unless the device autonegotiation advertisement
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
 * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
 *            E1000_SUCCESS at any other case.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
	DEBUGFUNC("e1000_set_d3_lplu_state");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
	if (hw->phy_type != e1000_phy_igp)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
	/* During driver activity LPLU should not be used or it will attain link
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
	 * from the lowest speeds starting from 10Mbps. The capability is used for
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
	 * Dx transitions and states */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
	if (hw->mac_type == e1000_82541_rev_2
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
	    || hw->mac_type == e1000_82547_rev_2) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
		    e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
	if (!active) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
		if (hw->mac_type == e1000_82541_rev_2 ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
		    hw->mac_type == e1000_82547_rev_2) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
			phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
			    e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
						phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
		 * Dx states where the power conservation is most important.  During
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
		 * driver activity we should enable SmartSpeed, so performance is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
		 * maintained. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
		if (hw->smart_speed == e1000_smart_speed_on) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
					       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
			phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
						phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
		} else if (hw->smart_speed == e1000_smart_speed_off) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
					       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
						phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
	} else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
		   || (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
		   || (hw->autoneg_advertised ==
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
		       AUTONEG_ADVERTISE_10_100_ALL)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
		if (hw->mac_type == e1000_82541_rev_2 ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
		    hw->mac_type == e1000_82547_rev_2) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
			phy_data |= IGP01E1000_GMII_FLEX_SPD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
			ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
			    e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
						phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
				return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
		/* When LPLU is enabled we should disable SmartSpeed */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
		    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
				       &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
		phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
		ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
		    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
					phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
 * e1000_set_vco_speed
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
 * Change VCO speed register to improve Bit Error Rate performance of SERDES.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
static s32 e1000_set_vco_speed(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
	u16 default_page = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
	DEBUGFUNC("e1000_set_vco_speed");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
	case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
		return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
	/* Set PHY register 30, page 5, bit 8 to 0 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
	ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
	    e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
	phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
	/* Set PHY register 30, page 4, bit 11 to 1 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
	phy_data |= M88E1000_PHY_VCO_REG_BIT11;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
	ret_val =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
	    e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
 * e1000_enable_mng_pass_thru - check for bmc pass through
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
 * Verifies the hardware needs to allow ARPs to be processed by the host
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
 * returns: - true/false
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
u32 e1000_enable_mng_pass_thru(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
	u32 manc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
	if (hw->asf_firmware_present) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
		manc = er32(MANC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
		if (!(manc & E1000_MANC_RCV_TCO_EN) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
		    !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
			return false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
		if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
			return true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
	return false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
	s32 ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
	u16 mii_status_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
	u16 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
	/* Polarity reversal workaround for forced 10F/10H links. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
	/* Disable the transmitter on the PHY */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
	/* This loop will early-out if the NO link condition has been met. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
	for (i = PHY_FORCE_TIME; i > 0; i--) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
		/* Read the MII Status Register and wait for Link Status bit
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
		 * to be clear.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
		if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
		mdelay(100);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
	/* Recommended delay time after link has been lost */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
	mdelay(1000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
	/* Now we will re-enable th transmitter on the PHY */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
	mdelay(50);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
	mdelay(50);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
	mdelay(50);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
		return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
	/* This loop will early-out if the link condition has been met. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
	for (i = PHY_FORCE_TIME; i > 0; i--) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
		/* Read the MII Status Register and wait for Link Status bit
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
		 * to be set.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
		if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
			return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
		if (mii_status_reg & MII_SR_LINK_STATUS)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
		mdelay(100);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
 * e1000_get_auto_rd_done
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
 * Check for EEPROM Auto Read bit done.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
 * returns: - E1000_ERR_RESET if fail to reset MAC
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
 *            E1000_SUCCESS at any other case.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
	DEBUGFUNC("e1000_get_auto_rd_done");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
	msleep(5);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
 * e1000_get_phy_cfg_done
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
 * @hw: Struct containing variables accessed by shared code
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
 * Checks if the PHY configuration is done
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
 * returns: - E1000_ERR_RESET if fail to reset MAC
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
 *            E1000_SUCCESS at any other case.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
	DEBUGFUNC("e1000_get_phy_cfg_done");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
	mdelay(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
}