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

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2199
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
15babd8d4205 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
15babd8d4205 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,
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
15babd8d4205 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
15babd8d4205 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.,
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
15babd8d4205 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>
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
/* e1000_hw.c
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include "e1000_hw-2.6.32-ethercat.h"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
15babd8d4205 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);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
				e1000_rev_polarity *polarity);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
					      bool link_up);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
				  u16 *max_length);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
				  struct e1000_phy_info *phy_info);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
				  struct e1000_phy_info *phy_info);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
				  u16 words, u16 *data);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
					u16 words, u16 *data);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
				  u16 phy_data);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
				 u16 *phy_data);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
				u16 *data);
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
				 u16 *data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
/* IGP cable length table */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
static const
15babd8d4205 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] = {
15babd8d4205 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,
15babd8d4205 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,
15babd8d4205 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,
15babd8d4205 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,
15babd8d4205 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,
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	    100,
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	    110, 110,
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	    120, 120
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
};
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static DEFINE_SPINLOCK(e1000_eeprom_lock);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	DEBUGFUNC("e1000_set_phy_type");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	if (hw->mac_type == e1000_undefined)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
		return -E1000_ERR_PHY_TYPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	switch (hw->phy_id) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	case M88E1000_E_PHY_ID:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	case M88E1000_I_PHY_ID:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	case M88E1011_I_PHY_ID:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	case M88E1111_I_PHY_ID:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
		hw->phy_type = e1000_phy_m88;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	case IGP01E1000_I_PHY_ID:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
		if (hw->mac_type == e1000_82541 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
		    hw->mac_type == e1000_82541_rev_2 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
		    hw->mac_type == e1000_82547 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
		    hw->mac_type == e1000_82547_rev_2) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
			hw->phy_type = e1000_phy_igp;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
		/* Should never have loaded on this device */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
		hw->phy_type = e1000_phy_undefined;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
		return -E1000_ERR_PHY_TYPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
	u32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
	u16 phy_saved_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
	DEBUGFUNC("e1000_phy_init_script");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	if (hw->phy_init_script) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
		msleep(20);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
		 * the end of this routine. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
		/* Disabled the PHY transmitter */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
		e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
		msleep(20);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
		e1000_write_phy_reg(hw, 0x0000, 0x0140);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
		msleep(5);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
		case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
		case e1000_82547:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
			e1000_write_phy_reg(hw, 0x1F95, 0x0001);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
			e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
			e1000_write_phy_reg(hw, 0x1F79, 0x0018);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
			e1000_write_phy_reg(hw, 0x1F30, 0x1600);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
			e1000_write_phy_reg(hw, 0x1F31, 0x0014);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
			e1000_write_phy_reg(hw, 0x1F32, 0x161C);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
			e1000_write_phy_reg(hw, 0x1F94, 0x0003);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
			e1000_write_phy_reg(hw, 0x1F96, 0x003F);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
			e1000_write_phy_reg(hw, 0x2010, 0x0008);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
		case e1000_82541_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
		case e1000_82547_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
			e1000_write_phy_reg(hw, 0x1F73, 0x0099);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
		default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
		e1000_write_phy_reg(hw, 0x0000, 0x3300);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
		msleep(20);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
		/* Now enable the transmitter */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		if (hw->mac_type == e1000_82547) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
			u16 fused, fine, coarse;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
			/* Move to analog registers page */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
			e1000_read_phy_reg(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
					   IGP01E1000_ANALOG_SPARE_FUSE_STATUS,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
					   &fused);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
			if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
				e1000_read_phy_reg(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
						   IGP01E1000_ANALOG_FUSE_STATUS,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
						   &fused);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
				fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
				coarse =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
				    fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
				if (coarse >
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
				    IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
					coarse -=
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
					    IGP01E1000_ANALOG_FUSE_COARSE_10;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
					fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
				} else if (coarse ==
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
					   IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
					fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
				fused =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
				    (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
				    (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
				    (coarse &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
				     IGP01E1000_ANALOG_FUSE_COARSE_MASK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
				e1000_write_phy_reg(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
						    IGP01E1000_ANALOG_FUSE_CONTROL,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
						    fused);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
				e1000_write_phy_reg(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
						    IGP01E1000_ANALOG_FUSE_BYPASS,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
						    IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	DEBUGFUNC("e1000_set_mac_type");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	switch (hw->device_id) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	case E1000_DEV_ID_82542:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
		switch (hw->revision_id) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
		case E1000_82542_2_0_REV_ID:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
			hw->mac_type = e1000_82542_rev2_0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
		case E1000_82542_2_1_REV_ID:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
			hw->mac_type = e1000_82542_rev2_1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
		default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
			/* Invalid 82542 revision ID */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
			return -E1000_ERR_MAC_TYPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	case E1000_DEV_ID_82543GC_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	case E1000_DEV_ID_82543GC_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
		hw->mac_type = e1000_82543;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	case E1000_DEV_ID_82544EI_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	case E1000_DEV_ID_82544EI_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	case E1000_DEV_ID_82544GC_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	case E1000_DEV_ID_82544GC_LOM:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
		hw->mac_type = e1000_82544;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	case E1000_DEV_ID_82540EM:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	case E1000_DEV_ID_82540EM_LOM:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	case E1000_DEV_ID_82540EP:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	case E1000_DEV_ID_82540EP_LOM:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	case E1000_DEV_ID_82540EP_LP:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		hw->mac_type = e1000_82540;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	case E1000_DEV_ID_82545EM_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	case E1000_DEV_ID_82545EM_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
		hw->mac_type = e1000_82545;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	case E1000_DEV_ID_82545GM_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	case E1000_DEV_ID_82545GM_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	case E1000_DEV_ID_82545GM_SERDES:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
		hw->mac_type = e1000_82545_rev_3;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	case E1000_DEV_ID_82546EB_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	case E1000_DEV_ID_82546EB_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
		hw->mac_type = e1000_82546;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	case E1000_DEV_ID_82546GB_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	case E1000_DEV_ID_82546GB_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	case E1000_DEV_ID_82546GB_SERDES:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	case E1000_DEV_ID_82546GB_PCIE:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	case E1000_DEV_ID_82546GB_QUAD_COPPER:
15babd8d4205 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:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
		hw->mac_type = e1000_82546_rev_3;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	case E1000_DEV_ID_82541EI:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	case E1000_DEV_ID_82541EI_MOBILE:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	case E1000_DEV_ID_82541ER_LOM:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		hw->mac_type = e1000_82541;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
	case E1000_DEV_ID_82541ER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	case E1000_DEV_ID_82541GI:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	case E1000_DEV_ID_82541GI_LF:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	case E1000_DEV_ID_82541GI_MOBILE:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		hw->mac_type = e1000_82541_rev_2;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	case E1000_DEV_ID_82547EI:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	case E1000_DEV_ID_82547EI_MOBILE:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		hw->mac_type = e1000_82547;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	case E1000_DEV_ID_82547GI:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		hw->mac_type = e1000_82547_rev_2;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
		/* Should never have loaded on this device */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
		return -E1000_ERR_MAC_TYPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
	case e1000_82547:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	case e1000_82541_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	case e1000_82547_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		hw->asf_firmware_present = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	 * FD mode
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	if (hw->mac_type == e1000_82543)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		hw->bad_tx_carr_stats_fd = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	if (hw->mac_type > e1000_82544)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		hw->has_smbus = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	u32 status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
	DEBUGFUNC("e1000_set_media_type");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
	if (hw->mac_type != e1000_82543) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
		/* tbi_compatibility is only valid on 82543 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
		hw->tbi_compatibility_en = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	switch (hw->device_id) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	case E1000_DEV_ID_82545GM_SERDES:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	case E1000_DEV_ID_82546GB_SERDES:
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
		case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
		case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
			hw->media_type = e1000_media_type_fiber;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
		default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
			status = er32(STATUS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
			if (status & E1000_STATUS_TBIMODE) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
				hw->media_type = e1000_media_type_fiber;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
				/* tbi_compatibility not valid on fiber */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
				hw->tbi_compatibility_en = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
				hw->media_type = e1000_media_type_copper;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
 * e1000_reset_hw: reset the hardware completely
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
 *
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	u32 ctrl_ext;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	u32 icr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	u32 manc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	u32 led_ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
	DEBUGFUNC("e1000_reset_hw");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
15babd8d4205 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 */
15babd8d4205 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) {
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
		e1000_pci_clear_mwi(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	DEBUGOUT("Masking off all interrupts\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	ew32(IMC, 0xffffffff);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	 * the global reset.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	ew32(RCTL, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	ew32(TCTL, E1000_TCTL_PSP);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	hw->tbi_compatibility_on = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	 * resetting the device
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	msleep(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
15babd8d4205 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 */
15babd8d4205 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)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
		ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		msleep(5);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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-
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	 * clearing, and should clear within a microsecond.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	 */
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	case e1000_82544:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	case e1000_82540:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	case e1000_82545:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	case e1000_82546:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	case e1000_82541_rev_2:
15babd8d4205 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
15babd8d4205 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 */
15babd8d4205 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));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	case e1000_82545_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	case e1000_82546_rev_3:
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		ew32(CTRL_DUP, (ctrl | E1000_CTRL_RST));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		ew32(CTRL, (ctrl | E1000_CTRL_RST));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	 * for reload to complete.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
	case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	case e1000_82543:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	case e1000_82544:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		/* Wait for reset to complete */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
		udelay(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		ctrl_ext = er32(CTRL_EXT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
		ctrl_ext |= E1000_CTRL_EXT_EE_RST;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		ew32(CTRL_EXT, ctrl_ext);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
		/* Wait for EEPROM reload */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
		msleep(2);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	case e1000_82541_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	case e1000_82547:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	case e1000_82547_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
		/* Wait for EEPROM reload */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		msleep(20);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	default:
15babd8d4205 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 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	/* Disable HW ARPs on ASF enabled adapters */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	if (hw->mac_type >= e1000_82540) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
		manc = er32(MANC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		manc &= ~(E1000_MANC_ARP_EN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		ew32(MANC, manc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
15babd8d4205 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)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
		e1000_phy_init_script(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		/* Configure activity LED after PHY reset */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		led_ctrl = er32(LEDCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
		ew32(LEDCTL, led_ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	DEBUGOUT("Masking off all interrupts\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	ew32(IMC, 0xffffffff);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	/* Clear any pending interrupt events. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	icr = er32(ICR);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	/* If MWI was previously enabled, reenable it. */
15babd8d4205 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) {
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
			e1000_pci_set_mwi(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
 *
15babd8d4205 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
15babd8d4205 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,
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	u32 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	u32 mta_size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	u32 ctrl_ext;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	DEBUGFUNC("e1000_init_hw");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	/* Initialize Identification LED */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	ret_val = e1000_id_led_init(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		DEBUGOUT("Error Initializing Identification LED\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	/* Set the media type and TBI compatibility */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	e1000_set_media_type(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	/* Disabling VLAN filtering. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	DEBUGOUT("Initializing the IEEE VLAN\n");
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
		ew32(VET, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	e1000_clear_vfta(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
15babd8d4205 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 */
15babd8d4205 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) {
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
		e1000_pci_clear_mwi(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		ew32(RCTL, E1000_RCTL_RST);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
		msleep(5);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	 * Address Registers (RARs 0 - 15).
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	e1000_init_rx_addrs(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
15babd8d4205 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 */
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		ew32(RCTL, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		msleep(1);
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
			e1000_pci_set_mwi(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	/* Zero out the Multicast HASH table */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	DEBUGOUT("Zeroing the MTA\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	mta_size = E1000_MC_TBL_SIZE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	for (i = 0; i < mta_size; i++) {
15babd8d4205 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);
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		 * occurring when accessing our register space */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	 * 82542 and 82543 silicon.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	 */
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		ew32(CTRL, ctrl | E1000_CTRL_PRIOR);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	case e1000_82545_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	case e1000_82546_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	default:
15babd8d4205 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. */
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
		    && e1000_pcix_get_mmrbc(hw) > 2048)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
			e1000_pcix_set_mmrbc(hw, 2048);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	ret_val = e1000_setup_link(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	/* Set the transmit descriptor write-back policy */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	if (hw->mac_type > e1000_82544) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		ctrl = er32(TXDCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		ctrl =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		    (ctrl & ~E1000_TXDCTL_WTHRESH) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		    E1000_TXDCTL_FULL_TX_DESC_WB;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		ew32(TXDCTL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	 * is no link.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	e1000_clear_hw_cntrs(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
15babd8d4205 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 ||
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		ctrl_ext = er32(CTRL_EXT);
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		 * error crash in a PCI slot. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		ew32(CTRL_EXT, ctrl_ext);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
/**
15babd8d4205 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.
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	u16 eeprom_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	DEBUGFUNC("e1000_adjust_serdes_amplitude");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
	case e1000_82545_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	case e1000_82546_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	                            &eeprom_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	if (eeprom_data != EEPROM_RESERVED_WORD) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
		/* Adjust SERDES output amplitude only. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
		eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
 *
15babd8d4205 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-
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
 * transmitter and receiver are not enabled.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	u32 ctrl_ext;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	u16 eeprom_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	DEBUGFUNC("e1000_setup_link");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
15babd8d4205 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
15babd8d4205 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,
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	if (hw->fc == E1000_FC_DEFAULT) {
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
					    1, &eeprom_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
		if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
			DEBUGOUT("EEPROM Read Error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
			return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
		}
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
			hw->fc = E1000_FC_NONE;
15babd8d4205 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) ==
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
			 EEPROM_WORD0F_ASM_DIR)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
			hw->fc = E1000_FC_TX_PAUSE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
			hw->fc = E1000_FC_FULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
		hw->fc &= (~E1000_FC_TX_PAUSE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
15babd8d4205 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))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		hw->fc &= (~E1000_FC_RX_PAUSE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	hw->original_fc = hw->fc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	 * Extended Device Control reg with that info.
15babd8d4205 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
15babd8d4205 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()
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	 * or e1000_phy_setup() is called.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	if (hw->mac_type == e1000_82543) {
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
					    1, &eeprom_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
		if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
			DEBUGOUT("EEPROM Read Error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
			return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		}
15babd8d4205 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) <<
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
			    SWDPIO__EXT_SHIFT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		ew32(CTRL_EXT, ctrl_ext);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
15babd8d4205 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. */
15babd8d4205 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) ?
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	 * initialize these registers.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	DEBUGOUT
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	ew32(FCT, FLOW_CONTROL_TYPE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	ew32(FCTTV, hw->fc_pause_time);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
15babd8d4205 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,
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	 * registers will be set to 0.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	if (!(hw->fc & E1000_FC_TX_PAUSE)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		ew32(FCRTL, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
		ew32(FCRTH, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	} else {
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
		if (hw->fc_send_xon) {
15babd8d4205 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));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
			ew32(FCRTH, hw->fc_high_water);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
			ew32(FCRTL, hw->fc_low_water);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
			ew32(FCRTH, hw->fc_high_water);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
 *
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
 * and receiver are not enabled.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	u32 status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	u32 txcw = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	u32 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	u32 signal = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	DEBUGFUNC("e1000_setup_fiber_serdes_link");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	 * set in the EEPROM.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	ctrl = er32(CTRL);
15babd8d4205 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)
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	ret_val = e1000_adjust_serdes_amplitude(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	/* Take the link out of reset */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	ctrl &= ~(E1000_CTRL_LRST);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	/* Adjust VCO speed to improve BER performance */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	ret_val = e1000_set_vco_speed(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	e1000_config_collision_dist(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	 *
15babd8d4205 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:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	 *      0:  Flow control is completely disabled
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	 *          not send pause frames).
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	 *          not support receiving pause frames).
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	switch (hw->fc) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	case E1000_FC_NONE:
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	case E1000_FC_RX_PAUSE:
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	case E1000_FC_TX_PAUSE:
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		 * software over-ride.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	case E1000_FC_FULL:
15babd8d4205 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. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
		DEBUGOUT("Flow control param set incorrectly\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
		return -E1000_ERR_CONFIG;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	DEBUGOUT("Auto-negotiation enabled\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	ew32(TXCW, txcw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	hw->txcw = txcw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	msleep(1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
15babd8d4205 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"
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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).
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	 */
15babd8d4205 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 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	    (er32(CTRL) & E1000_CTRL_SWDPIN1) == signal) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
		DEBUGOUT("Looking for Link\n");
15babd8d4205 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++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
			msleep(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
			status = er32(STATUS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
			if (status & E1000_STATUS_LU)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
		if (i == (LINK_UP_TIMEOUT / 10)) {
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
			hw->autoneg_failed = 1;
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
			 * non-autonegotiating link partners.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
			 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
			ret_val = e1000_check_for_link(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
			if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
				DEBUGOUT("Error while checking for link\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
			hw->autoneg_failed = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
			hw->autoneg_failed = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
			DEBUGOUT("Valid Link Found\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
		DEBUGOUT("No Signal Detected\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
 *
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	DEBUGFUNC("e1000_copper_link_preconfig");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	ctrl = er32(CTRL);
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	if (hw->mac_type > e1000_82543) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		ctrl |= E1000_CTRL_SLU;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
		ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		ctrl |=
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
		ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
		ret_val = e1000_phy_hw_reset(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	/* Make sure we have a valid PHY */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	ret_val = e1000_detect_gig_phy(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	if (ret_val) {
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	}
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
15babd8d4205 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) */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	ret_val = e1000_set_phy_mode(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
15babd8d4205 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) ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	    (hw->mac_type == e1000_82546_rev_3)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
		phy_data |= 0x00000008;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
		ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	if (hw->mac_type <= e1000_82543 ||
15babd8d4205 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 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	    hw->mac_type == e1000_82541_rev_2
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	    || hw->mac_type == e1000_82547_rev_2)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		hw->phy_reset_disable = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	u32 led_ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	DEBUGFUNC("e1000_copper_link_igp_setup");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	if (hw->phy_reset_disable)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	ret_val = e1000_phy_reset(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		DEBUGOUT("Error Resetting the PHY\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	msleep(15);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	/* Configure activity LED after PHY reset */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	led_ctrl = er32(LEDCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	led_ctrl &= IGP_ACTIVITY_LED_MASK;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	ew32(LEDCTL, led_ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	if (hw->phy_type == e1000_phy_igp) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		/* disable lplu d3 during driver init */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
		if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
			DEBUGOUT("Error Disabling LPLU D3\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	/* Configure mdi-mdix settings */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
15babd8d4205 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)) {
15babd8d4205 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;
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
		phy_data &=
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
		    ~(IGP01E1000_PSCR_AUTO_MDIX |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		      IGP01E1000_PSCR_FORCE_MDI_MDIX);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
		hw->mdix = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
	} else {
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
		switch (hw->mdix) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
		case 1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
			phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
		case 2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
			phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
		case 0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
		default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
			phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	}
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	/* set auto-master slave resolution settings */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	if (hw->autoneg) {
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
15babd8d4205 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)
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
15babd8d4205 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)
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		 * should disable SmartSpeed and enable Auto MasterSlave
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		 * resolution as hardware default. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
		if (hw->autoneg_advertised == ADVERTISE_1000_FULL) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
			/* Disable SmartSpeed */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
					       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
						phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
			/* Set auto Master/Slave resolution process */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
			phy_data &= ~CR_1000T_MS_ENABLE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		/* load defaults for future use */
15babd8d4205 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) ?
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		    ((phy_data & CR_1000T_MS_VALUE) ?
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		     e1000_ms_force_master :
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
		     e1000_ms_force_slave) : e1000_ms_auto;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		switch (phy_ms_setting) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		case e1000_ms_force_master:
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		case e1000_ms_force_slave:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
			phy_data |= CR_1000T_MS_ENABLE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
			phy_data &= ~(CR_1000T_MS_VALUE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		case e1000_ms_auto:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
			phy_data &= ~CR_1000T_MS_ENABLE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		}
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	DEBUGFUNC("e1000_copper_link_mgp_setup");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
	if (hw->phy_reset_disable)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
15babd8d4205 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. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	/* Options:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	 *   MDI/MDI-X = 0 (default)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	 *   0 - Auto for all speeds
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	 *   1 - MDI mode
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	 *   2 - MDI-X mode
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	switch (hw->mdix) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
	case 1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	case 2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	case 3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	case 0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	/* Options:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	 *   disable_polarity_correction = 0 (default)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	 *       Automatic Correction for Reversed Cable Polarity
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	 *   0 - Disabled
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	 *   1 - Enabled
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	if (hw->disable_polarity_correction == 1)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
15babd8d4205 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) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		 * to 25MHz clock.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
				       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		if ((hw->phy_revision == E1000_REVISION_2) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		    (hw->phy_id == M88E1111_I_PHY_ID)) {
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
			phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
			ret_val = e1000_write_phy_reg(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
						      M88E1000_EXT_PHY_SPEC_CTRL,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
						      phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
			/* Configure Master and Slave downshift values */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
				      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
			ret_val = e1000_write_phy_reg(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
						      M88E1000_EXT_PHY_SPEC_CTRL,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
						      phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	ret_val = e1000_phy_reset(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
		DEBUGOUT("Error Resetting the PHY\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
 * e1000_copper_link_autoneg - setup auto-neg
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
 * Setup auto-negotiation and flow control advertisements,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
 * and then perform auto-negotiation.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	DEBUGFUNC("e1000_copper_link_autoneg");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	if (hw->autoneg_advertised == 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
		hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
	ret_val = e1000_phy_setup_autoneg(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		DEBUGOUT("Error Setting up Auto-Negotiation\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	DEBUGOUT("Restarting Auto-Neg\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
15babd8d4205 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
15babd8d4205 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).
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	if (hw->wait_autoneg_complete) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
		ret_val = e1000_wait_autoneg(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
		if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
			DEBUGOUT
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	hw->get_link_status = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
 * e1000_copper_link_postconfig - post link setup
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
 *
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
 *      if we are on 82543.  If we
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
 *      collision distance in the Transmit Control Register.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
 *      the link partner.
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	DEBUGFUNC("e1000_copper_link_postconfig");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	if (hw->mac_type >= e1000_82544) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
		e1000_config_collision_dist(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
	} else {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
		if (ret_val) {
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	}
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
	if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
		DEBUGOUT("Error Configuring Flow Control\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	/* Config DSP to improve Giga link quality */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	if (hw->phy_type == e1000_phy_igp) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
		if (ret_val) {
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
	u16 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	DEBUGFUNC("e1000_setup_copper_link");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	ret_val = e1000_copper_link_preconfig(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	if (hw->phy_type == e1000_phy_igp) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
			return ret_val;
15babd8d4205 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) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	if (hw->autoneg) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
		/* Setup autoneg and flow control advertisement
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		 * and perform autonegotiation */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
		ret_val = e1000_copper_link_autoneg(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
	} else {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		 * depending on value from forced_speed_duplex. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		DEBUGOUT("Forcing speed and duplex\n");
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
		if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
			DEBUGOUT("Error Forcing Speed and Duplex\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	 * valid.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	for (i = 0; i < 10; i++) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
			return ret_val;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
		if (phy_data & MII_SR_LINK_STATUS) {
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
			ret_val = e1000_copper_link_postconfig(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
			DEBUGOUT("Valid link established!!!\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
			return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		udelay(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	DEBUGOUT("Unable to establish link!!!\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
 * e1000_phy_setup_autoneg - phy settings
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	u16 mii_autoneg_adv_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	u16 mii_1000t_ctrl_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	DEBUGFUNC("e1000_phy_setup_autoneg");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
15babd8d4205 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). */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
15babd8d4205 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). */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	 * individually.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	 * the  1000Base-T Control Register (Address 9).
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
15babd8d4205 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? */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
		DEBUGOUT("Advertise 10mb Half duplex\n");
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
15babd8d4205 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? */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		DEBUGOUT("Advertise 10mb Full duplex\n");
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
15babd8d4205 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? */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
		DEBUGOUT("Advertise 100mb Half duplex\n");
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
15babd8d4205 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? */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		DEBUGOUT("Advertise 100mb Full duplex\n");
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		DEBUGOUT
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
15babd8d4205 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? */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		DEBUGOUT("Advertise 1000mb Full duplex\n");
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	 * setup the PHY advertisement registers accordingly.  If
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	 *
15babd8d4205 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:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	 *      0:  Flow control is completely disabled
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
	 *          but not send pause frames).
15babd8d4205 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
15babd8d4205 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).
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	 *          in the EEPROM is used.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	switch (hw->fc) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	case E1000_FC_NONE:	/* 0 */
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		 * software over-ride.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	case E1000_FC_RX_PAUSE:	/* 1 */
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		 * disabled, by a software over-ride.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
		 */
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		 *hw's ability to send PAUSE frames.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	case E1000_FC_TX_PAUSE:	/* 2 */
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		 * disabled, by a software over-ride.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		 */
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
	case E1000_FC_FULL:	/* 3 */
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		 * over-ride.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
		DEBUGOUT("Flow control param set incorrectly\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
		return -E1000_ERR_CONFIG;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	u16 mii_ctrl_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	u16 mii_status_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	u16 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	DEBUGFUNC("e1000_phy_force_speed_duplex");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	hw->fc = E1000_FC_NONE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	DEBUGOUT1("hw->fc = %d\n", hw->fc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	/* Read the Device Control Register. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
	ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
	ctrl &= ~(DEVICE_SPEED_MASK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	/* Clear the Auto Speed Detect Enable bit. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
	ctrl &= ~E1000_CTRL_ASDE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	/* Read the MII Control Register. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	/* Are we forcing Full or Half Duplex? */
15babd8d4205 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 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
	    hw->forced_speed_duplex == e1000_10_full) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		 * Device and MII Control Registers.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		ctrl |= E1000_CTRL_FD;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		mii_ctrl_reg |= MII_CR_FULL_DUPLEX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
		DEBUGOUT("Full Duplex\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
	} else {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		 * the Device and MII Control Registers.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		ctrl &= ~E1000_CTRL_FD;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		mii_ctrl_reg &= ~MII_CR_FULL_DUPLEX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		DEBUGOUT("Half Duplex\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
	/* Are we forcing 100Mbps??? */
15babd8d4205 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 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	    hw->forced_speed_duplex == e1000_100_half) {
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		ctrl |= E1000_CTRL_SPD_100;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		mii_ctrl_reg |= MII_CR_SPEED_100;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
		DEBUGOUT("Forcing 100mb ");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	} else {
15babd8d4205 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. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
		mii_ctrl_reg |= MII_CR_SPEED_10;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		DEBUGOUT("Forcing 10mb ");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	e1000_config_collision_dist(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	if (hw->phy_type == e1000_phy_m88) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		 * forced whenever speed are duplex are forced.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
		DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
		mii_ctrl_reg |= MII_CR_RESET;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
		/* Disable MDI-X support for 10/100 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	} else {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		 * forced whenever speed or duplex are forced.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
		phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
15babd8d4205 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. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	udelay(1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
15babd8d4205 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.
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	 * the default.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	if (hw->wait_autoneg_complete) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
		/* We will wait for autoneg to complete. */
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		mii_status_reg = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
15babd8d4205 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. */
15babd8d4205 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--) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
			 * to be set.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
			 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
			msleep(100);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		}
15babd8d4205 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)) {
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
			ret_val = e1000_phy_reset_dsp(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
			if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
				DEBUGOUT("Error Resetting PHY DSP\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		}
15babd8d4205 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.  */
15babd8d4205 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--) {
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
			msleep(100);
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
			 * to be set.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
			 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
	if (hw->phy_type == e1000_phy_m88) {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
				       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
					phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
		ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		    && (!hw->autoneg)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
		    && (hw->forced_speed_duplex == e1000_10_full
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
			|| hw->forced_speed_duplex == e1000_10_half)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
			ret_val = e1000_polarity_reversal_workaround(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
 *
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
 * information from the Device Status register.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
	u32 tctl, coll_dist;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
	DEBUGFUNC("e1000_config_collision_dist");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
	if (hw->mac_type < e1000_82543)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
		coll_dist = E1000_COLLISION_DISTANCE_82542;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
	else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		coll_dist = E1000_COLLISION_DISTANCE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	tctl = er32(TCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	tctl &= ~E1000_TCTL_COLD;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	tctl |= coll_dist << E1000_COLD_SHIFT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
	ew32(TCTL, tctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
 *
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
 * be passed in.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
	DEBUGFUNC("e1000_config_mac_to_phy");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	 * MAC speed/duplex configuration.*/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
	if (hw->mac_type >= e1000_82544)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	 * and Duplex.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
	ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	 * registers depending on negotiated values.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	if (phy_data & M88E1000_PSSR_DPLX)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		ctrl |= E1000_CTRL_FD;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
	else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
		ctrl &= ~E1000_CTRL_FD;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
	e1000_config_collision_dist(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	 * negotiated values.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
	 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
		ctrl |= E1000_CTRL_SPD_1000;
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
		ctrl |= E1000_CTRL_SPD_100;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
 * Forces the MAC's flow control settings.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	DEBUGFUNC("e1000_force_mac_fc");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	 * receive flow control.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
	 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	 * according to the "hw->fc" parameter.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	 *
15babd8d4205 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:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	 *      0:  Flow control is completely disabled
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	 *          frames but not send pause frames).
15babd8d4205 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
15babd8d4205 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).
15babd8d4205 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.
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	switch (hw->fc) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	case E1000_FC_NONE:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
	case E1000_FC_RX_PAUSE:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
		ctrl &= (~E1000_CTRL_TFCE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
		ctrl |= E1000_CTRL_RFCE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	case E1000_FC_TX_PAUSE:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
		ctrl &= (~E1000_CTRL_RFCE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		ctrl |= E1000_CTRL_TFCE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	case E1000_FC_FULL:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
		DEBUGOUT("Flow control param set incorrectly\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		return -E1000_ERR_CONFIG;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
15babd8d4205 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) */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
		ctrl &= (~E1000_CTRL_TFCE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
 *
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	u16 mii_status_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	u16 mii_nway_adv_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
	u16 mii_nway_lp_ability_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
	u16 speed;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	u16 duplex;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	DEBUGFUNC("e1000_config_fc_after_link_up");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	 */
15babd8d4205 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))
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
		&& (hw->autoneg_failed))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	    || ((hw->media_type == e1000_media_type_copper)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
		&& (!hw->autoneg))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		ret_val = e1000_force_mac_fc(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
		if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
			DEBUGOUT("Error forcing flow control settings\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	 * flow control configured.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	 */
15babd8d4205 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) {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
		 * some "sticky" (latched) bits.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
			return ret_val;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
15babd8d4205 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) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
			 * read both the Auto Negotiation Advertisement Register
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
			 * negotiated.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
			 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
						     &mii_nway_adv_reg);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
				return ret_val;
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
						     &mii_nway_lp_ability_reg);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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,
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
			 * control is determined based upon these settings.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
			 * NOTE:  DC = Don't Care
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
			 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
			 *   LOCAL DEVICE  |   LINK PARTNER
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
			 *-------|---------|-------|---------|--------------------
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
			 *   0   |    0    |  DC   |   DC    | E1000_FC_NONE
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
			 *   0   |    1    |   0   |   DC    | E1000_FC_NONE
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
			 *   0   |    1    |   1   |    0    | E1000_FC_NONE
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
			 *   1   |    0    |   0   |   DC    | E1000_FC_NONE
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
			 *   1   |    1    |   0   |    0    | E1000_FC_NONE
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
			 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
			 */
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
			 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
			 * For Symmetric Flow Control:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
			 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
			 *   LOCAL DEVICE  |   LINK PARTNER
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
			 *-------|---------|-------|---------|--------------------
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
			 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
			 */
15babd8d4205 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) &&
15babd8d4205 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)) {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
				 * turn OFF  the TRANSMISSION of PAUSE frames.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
				 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
				if (hw->original_fc == E1000_FC_FULL) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
					hw->fc = E1000_FC_FULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
					DEBUGOUT("Flow Control = FULL.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
				} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
					hw->fc = E1000_FC_RX_PAUSE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
					DEBUGOUT
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
					    ("Flow Control = RX PAUSE frames only.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
				}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
			/* For receiving PAUSE frames ONLY.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
			 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
			 *   LOCAL DEVICE  |   LINK PARTNER
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
			 *-------|---------|-------|---------|--------------------
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
			 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
			 */
15babd8d4205 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) &&
15babd8d4205 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) &&
15babd8d4205 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) &&
15babd8d4205 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))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
			{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
				hw->fc = E1000_FC_TX_PAUSE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
				DEBUGOUT
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
				    ("Flow Control = TX PAUSE frames only.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
			/* For transmitting PAUSE frames ONLY.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
			 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
			 *   LOCAL DEVICE  |   LINK PARTNER
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
			 *-------|---------|-------|---------|--------------------
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
			 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
			 */
15babd8d4205 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) &&
15babd8d4205 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) &&
15babd8d4205 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) &&
15babd8d4205 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))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
			{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
				hw->fc = E1000_FC_RX_PAUSE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
				DEBUGOUT
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
				    ("Flow Control = RX PAUSE frames only.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
			}
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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)
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
			 */
15babd8d4205 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 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
				  hw->original_fc == E1000_FC_TX_PAUSE) ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
				 hw->fc_strict_ieee) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
				hw->fc = E1000_FC_NONE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
				DEBUGOUT("Flow Control = NONE.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
				hw->fc = E1000_FC_RX_PAUSE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
				DEBUGOUT
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
				    ("Flow Control = RX PAUSE frames only.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
15babd8d4205 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-
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
			 * enabled per IEEE 802.3 spec.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
			 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
				DEBUGOUT
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
				    ("Error getting link speed and duplex\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
			if (duplex == HALF_DUPLEX)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
				hw->fc = E1000_FC_NONE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
			 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
			ret_val = e1000_force_mac_fc(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
			if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
				DEBUGOUT
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
				    ("Error forcing flow control settings\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
			DEBUGOUT
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
/**
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
 * @hw: pointer to the HW structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
 *
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	u32 rxcw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	u32 status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	s32 ret_val = E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	DEBUGFUNC("e1000_check_for_serdes_link_generic");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
	status = er32(STATUS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	rxcw = er32(RXCW);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	/*
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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),
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	 * time to complete.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
15babd8d4205 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))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
		if (hw->autoneg_failed == 0) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
			hw->autoneg_failed = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
			goto out;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
		}
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
		/* Disable auto-negotiation in the TXCW register */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
		ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
		ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
		ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
		/* Configure Flow Control after forcing link up. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
		if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
			DEBUGOUT("Error configuring flow control\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
			goto out;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
		}
15babd8d4205 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)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
		/*
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
		 */
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		ew32(TXCW, hw->txcw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
		hw->serdes_has_link = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
		/*
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
		 * serdes media type.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
		/* SYNCH bit and IV bit are sticky. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
		udelay(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
		rxcw = er32(RXCW);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
		if (rxcw & E1000_RXCW_SYNCH) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
			if (!(rxcw & E1000_RXCW_IV)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
				hw->serdes_has_link = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
				DEBUGOUT("SERDES: Link up - forced.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
			hw->serdes_has_link = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
			DEBUGOUT("SERDES: Link down - force failed.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	if (E1000_TXCW_ANE & er32(TXCW)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
		status = er32(STATUS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
		if (status & E1000_STATUS_LU) {
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
			udelay(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
			rxcw = er32(RXCW);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
			if (rxcw & E1000_RXCW_SYNCH) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
				if (!(rxcw & E1000_RXCW_IV)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
					hw->serdes_has_link = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
					DEBUGOUT("SERDES: Link up - autoneg "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
						 "completed successfully.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
				} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
					hw->serdes_has_link = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
					DEBUGOUT("SERDES: Link down - invalid"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
						 "codewords detected in autoneg.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
				}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
				hw->serdes_has_link = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
				DEBUGOUT("SERDES: Link down - no sync.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
			hw->serdes_has_link = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
			DEBUGOUT("SERDES: Link down - autoneg failed\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
      out:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
 * e1000_check_for_link
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
 *
15babd8d4205 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.
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	u32 rxcw = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	u32 status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	u32 rctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	u32 icr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	u32 signal = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
	DEBUGFUNC("e1000_check_for_link");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
	ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	status = er32(STATUS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	 */
15babd8d4205 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) ||
15babd8d4205 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)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
		rxcw = er32(RXCW);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
			signal =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
			    (hw->mac_type >
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
			     e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
			if (status & E1000_STATUS_LU)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
				hw->get_link_status = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	 * Errors.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	 */
15babd8d4205 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) {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		 * of the PHY.
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
			return ret_val;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
		if (phy_data & MII_SR_LINK_STATUS) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
			hw->get_link_status = false;
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
			 * link-up */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
			e1000_check_downshift(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
			 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
			if ((hw->mac_type == e1000_82544
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
			     || hw->mac_type == e1000_82543) && (!hw->autoneg)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
			    && (hw->forced_speed_duplex == e1000_10_full
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
				|| hw->forced_speed_duplex == e1000_10_half)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
				ew32(IMC, 0xffffffff);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
				ret_val =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
				    e1000_polarity_reversal_workaround(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
				icr = er32(ICR);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
				ew32(ICS, (icr & ~E1000_ICS_LSC));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
				ew32(IMS, IMS_ENABLE_MASK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
			/* No link detected */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
			return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		if (!hw->autoneg)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
			return -E1000_ERR_CONFIG;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
15babd8d4205 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 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
		 * settings.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
		if (hw->mac_type >= e1000_82544)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
			e1000_config_collision_dist(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
		else {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
			if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
				DEBUGOUT
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
				    ("Error configuring MAC to PHY settings\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
		if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
			DEBUGOUT("Error configuring flow control\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
		if (hw->tbi_compatibility_en) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
			u16 speed, duplex;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
			if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
				DEBUGOUT
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
				    ("Error getting link speed and duplex\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
			if (speed != SPEED_1000) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
				 * to enable TBI compatibility.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
				 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
				if (hw->tbi_compatibility_on) {
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
					rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
					rctl &= ~E1000_RCTL_SBP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
					ew32(RCTL, rctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
					hw->tbi_compatibility_on = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
				}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
			} else {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
				 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
				if (!hw->tbi_compatibility_on) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
					hw->tbi_compatibility_on = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
					rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
					rctl |= E1000_RCTL_SBP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
					ew32(RCTL, rctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
				}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
15babd8d4205 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) ||
15babd8d4205 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))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
		e1000_check_for_serdes_link_generic(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
 * e1000_get_speed_and_duplex
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
 * @speed: Speed of the connection
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
 * @duplex: Duplex setting of the connection
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
	u32 status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	DEBUGFUNC("e1000_get_speed_and_duplex");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	if (hw->mac_type >= e1000_82543) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		status = er32(STATUS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
		if (status & E1000_STATUS_SPEED_1000) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
			*speed = SPEED_1000;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
			DEBUGOUT("1000 Mbs, ");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
		} else if (status & E1000_STATUS_SPEED_100) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
			*speed = SPEED_100;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
			DEBUGOUT("100 Mbs, ");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
			*speed = SPEED_10;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
			DEBUGOUT("10 Mbs, ");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
		if (status & E1000_STATUS_FD) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
			*duplex = FULL_DUPLEX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
			DEBUGOUT("Full Duplex\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
			*duplex = HALF_DUPLEX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
			DEBUGOUT(" Half Duplex\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		DEBUGOUT("1000 Mbs, Full Duplex\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
		*speed = SPEED_1000;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
		*duplex = FULL_DUPLEX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	 */
15babd8d4205 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) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
15babd8d4205 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))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
			*duplex = HALF_DUPLEX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			if ((*speed == SPEED_100
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
			     && !(phy_data & NWAY_LPAR_100TX_FD_CAPS))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
			    || (*speed == SPEED_10
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
				&& !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
				*duplex = HALF_DUPLEX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
 * e1000_wait_autoneg
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
 *
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	u16 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
	DEBUGFUNC("e1000_wait_autoneg");
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
15babd8d4205 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. */
15babd8d4205 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--) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
		 * Complete bit to be set.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
			return ret_val;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
		if (phy_data & MII_SR_AUTONEG_COMPLETE) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
			return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		msleep(100);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
 * @ctrl: Device control register's current value
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
{
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	 * bit), and then delay 10 microseconds.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
	ew32(CTRL, (*ctrl | E1000_CTRL_MDC));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
	udelay(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
 * @ctrl: Device control register's current value
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
{
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
	 * bit), and then delay 10 microseconds.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
	ew32(CTRL, (*ctrl & ~E1000_CTRL_MDC));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
	udelay(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
 * @count: Number of bits to shift out
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
 *
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	u32 mask;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	mask = 0x01;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
	mask <<= (count - 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
15babd8d4205 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. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	while (mask) {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
		 * raising and lowering the clock.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
		if (data & mask)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
			ctrl |= E1000_CTRL_MDIO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
		else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
			ctrl &= ~E1000_CTRL_MDIO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
		ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		udelay(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		e1000_raise_mdi_clk(hw, &ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
		e1000_lower_mdi_clk(hw, &ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
		mask = mask >> 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
 *
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	u16 data = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	u8 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 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"
15babd8d4205 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),
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
	ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
	ctrl &= ~E1000_CTRL_MDIO_DIR;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
	ctrl &= ~E1000_CTRL_MDIO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	 * last bit of the Register Address.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	e1000_raise_mdi_clk(hw, &ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	e1000_lower_mdi_clk(hw, &ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
15babd8d4205 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++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		data = data << 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
		e1000_raise_mdi_clk(hw, &ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		ctrl = er32(CTRL);
15babd8d4205 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". */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
		if (ctrl & E1000_CTRL_MDIO)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
			data |= 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
		e1000_lower_mdi_clk(hw, &ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	e1000_raise_mdi_clk(hw, &ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
	e1000_lower_mdi_clk(hw, &ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
	return data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
 * page, sets the page first.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	u32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	DEBUGFUNC("e1000_read_phy_reg");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
	if ((hw->phy_type == e1000_phy_igp) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
						 (u16) reg_addr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
					phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
				 u16 *phy_data)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
	u32 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	u32 mdic = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	const u32 phy_addr = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
	DEBUGFUNC("e1000_read_phy_reg_ex");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
		return -E1000_ERR_PARAM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	if (hw->mac_type > e1000_82543) {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		 * PHY to retrieve the desired data.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
		mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
			(phy_addr << E1000_MDIC_PHY_SHIFT) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
			(E1000_MDIC_OP_READ));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
		ew32(MDIC, mdic);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
		for (i = 0; i < 64; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
			udelay(50);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
			mdic = er32(MDIC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
			if (mdic & E1000_MDIC_READY)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
		if (!(mdic & E1000_MDIC_READY)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
			DEBUGOUT("MDI Read did not complete\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
			return -E1000_ERR_PHY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
		if (mdic & E1000_MDIC_ERROR) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
			DEBUGOUT("MDI Error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
			return -E1000_ERR_PHY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
		*phy_data = (u16) mdic;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	} else {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
		 * consecutive "1" bits.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		 * defined as follows:
15babd8d4205 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>
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
		mdic = ((reg_addr) | (phy_addr << 5) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
			(PHY_OP_READ << 10) | (PHY_SOF << 12));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
		 * register address.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
/**
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
 *
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
 * @data: data to write to the PHY
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
 * Writes a value to a PHY register
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	u32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	DEBUGFUNC("e1000_write_phy_reg");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
	if ((hw->phy_type == e1000_phy_igp) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
						 (u16) reg_addr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
					 phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
				  u16 phy_data)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	u32 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
	u32 mdic = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	const u32 phy_addr = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	DEBUGFUNC("e1000_write_phy_reg_ex");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
		return -E1000_ERR_PARAM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	if (hw->mac_type > e1000_82543) {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
		mdic = (((u32) phy_data) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
			(reg_addr << E1000_MDIC_REG_SHIFT) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
			(phy_addr << E1000_MDIC_PHY_SHIFT) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
			(E1000_MDIC_OP_WRITE));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
		ew32(MDIC, mdic);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
		for (i = 0; i < 641; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
			udelay(5);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
			mdic = er32(MDIC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
			if (mdic & E1000_MDIC_READY)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
		if (!(mdic & E1000_MDIC_READY)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
			DEBUGOUT("MDI Write did not complete\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
			return -E1000_ERR_PHY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
	} else {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
		 * consecutive "1" bits.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
		 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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:
15babd8d4205 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>.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		 */
15babd8d4205 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) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
			(PHY_OP_WRITE << 12) | (PHY_SOF << 14));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		mdic <<= 16;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		mdic |= (u32) phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
	u32 ctrl, ctrl_ext;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
	u32 led_ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
	DEBUGFUNC("e1000_phy_hw_reset");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	DEBUGOUT("Resetting Phy...\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
	if (hw->mac_type > e1000_82543) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
		 * bit. Then, take it out of reset.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		 * and deassert.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		msleep(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
		ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	} else {
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		ctrl_ext = er32(CTRL_EXT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		ew32(CTRL_EXT, ctrl_ext);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
		msleep(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
		ew32(CTRL_EXT, ctrl_ext);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	udelay(150);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
15babd8d4205 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)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		/* Configure activity LED after PHY reset */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		led_ctrl = er32(LEDCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
		ew32(LEDCTL, led_ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	/* Wait for FW to finish PHY configuration. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
	if (ret_val != E1000_SUCCESS)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
	return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
 * Resets the PHY
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
	DEBUGFUNC("e1000_phy_reset");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
	switch (hw->phy_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	case e1000_phy_igp:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
		ret_val = e1000_phy_hw_reset(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
	default:
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
		phy_data |= MII_CR_RESET;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
		udelay(1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	if (hw->phy_type == e1000_phy_igp)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
		e1000_phy_init_script(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
	s32 phy_init_status, ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	u16 phy_id_high, phy_id_low;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	bool match = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	DEBUGFUNC("e1000_detect_gig_phy");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	if (hw->phy_id != 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
15babd8d4205 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. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	udelay(20);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
15babd8d4205 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);
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	case e1000_82543:
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
			match = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	case e1000_82544:
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
			match = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
	case e1000_82540:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	case e1000_82545:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	case e1000_82545_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	case e1000_82546:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	case e1000_82546_rev_3:
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
			match = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
	case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	case e1000_82541_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	case e1000_82547:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	case e1000_82547_rev_2:
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
			match = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
	default:
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		return -E1000_ERR_CONFIG;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	}
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
	if ((match) && (phy_init_status == E1000_SUCCESS)) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	}
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	return -E1000_ERR_PHY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
 * e1000_phy_reset_dsp - reset DSP
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
 * Resets the PHY's DSP
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	DEBUGFUNC("e1000_phy_reset_dsp");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
	do {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
			break;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
			break;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		ret_val = E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
	} while (0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
	return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
 * @phy_info: PHY information structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
 *
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
				  struct e1000_phy_info *phy_info)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	s32 ret_val;
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
	e1000_rev_polarity polarity;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
	DEBUGFUNC("e1000_phy_igp_get_info");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
15babd8d4205 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,
15babd8d4205 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. */
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	/* IGP01E1000 does not need to support it. */
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
	/* IGP01E1000 always correct polarity reversal */
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	/* Check polarity status */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	ret_val = e1000_check_polarity(hw, &polarity);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
	phy_info->cable_polarity = polarity;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	phy_info->mdix_mode =
15babd8d4205 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) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
				 IGP01E1000_PSSR_MDIX_SHIFT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
15babd8d4205 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 */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
15babd8d4205 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) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
15babd8d4205 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;
15babd8d4205 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) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
		/* Get cable length */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
		/* Translate to old method */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		average = (max_length + min_length) / 2;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		if (average <= e1000_igp_cable_length_50)
15babd8d4205 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;
15babd8d4205 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)
15babd8d4205 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;
15babd8d4205 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)
15babd8d4205 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;
15babd8d4205 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)
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
		else
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
 * @phy_info: PHY information structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
 *
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
				  struct e1000_phy_info *phy_info)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	e1000_rev_polarity polarity;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
	DEBUGFUNC("e1000_phy_m88_get_info");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
15babd8d4205 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,
15babd8d4205 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. */
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	phy_info->extended_10bt_distance =
15babd8d4205 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) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	     M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	    e1000_10bt_ext_dist_enable_lower :
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	    e1000_10bt_ext_dist_enable_normal;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	phy_info->polarity_correction =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	    ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	     M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	/* Check polarity status */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	ret_val = e1000_check_polarity(hw, &polarity);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	phy_info->cable_polarity = polarity;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
	phy_info->mdix_mode =
15babd8d4205 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) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
				 M88E1000_PSSR_MDIX_SHIFT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
15babd8d4205 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) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
		 * are only valid at 1000 Mbps.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		phy_info->cable_length =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
		    (e1000_cable_length) ((phy_data &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
					   M88E1000_PSSR_CABLE_LENGTH) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
					  M88E1000_PSSR_CABLE_LENGTH_SHIFT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
15babd8d4205 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) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
15babd8d4205 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;
15babd8d4205 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) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
 * e1000_phy_get_info - request phy info
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
 * @phy_info: PHY information structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
 * Get PHY information from various PHY registers
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
	DEBUGFUNC("e1000_phy_get_info");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
15babd8d4205 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;
15babd8d4205 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;
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	phy_info->downshift = e1000_downshift_undefined;
15babd8d4205 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;
15babd8d4205 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;
15babd8d4205 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;
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
15babd8d4205 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) {
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
		return -E1000_ERR_CONFIG;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
15babd8d4205 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) {
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
		return -E1000_ERR_CONFIG;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	if (hw->phy_type == e1000_phy_igp)
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	else
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	DEBUGFUNC("e1000_validate_mdi_settings");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
15babd8d4205 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)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
		DEBUGOUT("Invalid MDI setting detected\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
		hw->mdix = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
		return -E1000_ERR_CONFIG;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
 * is configured.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	u32 eecd = er32(EECD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	s32 ret_val = E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	u16 eeprom_size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	DEBUGFUNC("e1000_init_eeprom_params");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
	case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
	case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	case e1000_82543:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
	case e1000_82544:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
		eeprom->type = e1000_eeprom_microwire;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
		eeprom->word_size = 64;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
		eeprom->opcode_bits = 3;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
		eeprom->address_bits = 6;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
		eeprom->delay_usec = 50;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	case e1000_82540:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	case e1000_82545:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	case e1000_82545_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	case e1000_82546:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	case e1000_82546_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		eeprom->type = e1000_eeprom_microwire;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
		eeprom->opcode_bits = 3;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
		eeprom->delay_usec = 50;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
		if (eecd & E1000_EECD_SIZE) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
			eeprom->word_size = 256;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
			eeprom->address_bits = 8;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
			eeprom->word_size = 64;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
			eeprom->address_bits = 6;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	case e1000_82541_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	case e1000_82547:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	case e1000_82547_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
		if (eecd & E1000_EECD_TYPE) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
			eeprom->type = e1000_eeprom_spi;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
			eeprom->opcode_bits = 8;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
			eeprom->delay_usec = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
			if (eecd & E1000_EECD_ADDR_BITS) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
				eeprom->page_size = 32;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
				eeprom->address_bits = 16;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
				eeprom->page_size = 8;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
				eeprom->address_bits = 8;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
			eeprom->type = e1000_eeprom_microwire;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
			eeprom->opcode_bits = 3;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
			eeprom->delay_usec = 50;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
			if (eecd & E1000_EECD_ADDR_BITS) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
				eeprom->word_size = 256;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
				eeprom->address_bits = 8;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
				eeprom->word_size = 64;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
				eeprom->address_bits = 6;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	if (eeprom->type == e1000_eeprom_spi) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
		 * 32KB (incremented by powers of 2).
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		 */
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
		eeprom->word_size = 64;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
		eeprom_size =
15babd8d4205 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;
15babd8d4205 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
15babd8d4205 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)
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
		if (eeprom_size)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
			eeprom_size++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
 * @eecd: EECD's current value
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
{
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
	 * wait <delay> microseconds.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	*eecd = *eecd | E1000_EECD_SK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
	ew32(EECD, *eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
	udelay(hw->eeprom.delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
 * @eecd: EECD's current value
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
{
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	 * wait 50 microseconds.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	*eecd = *eecd & ~E1000_EECD_SK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	ew32(EECD, *eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	udelay(hw->eeprom.delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
 * @data: data to send to the EEPROM
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
 * @count: number of bits to shift out
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	u32 eecd;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	u32 mask;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	mask = 0x01 << (count - 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
	eecd = er32(EECD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	if (eeprom->type == e1000_eeprom_microwire) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
		eecd &= ~E1000_EECD_DO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
	} else if (eeprom->type == e1000_eeprom_spi) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
		eecd |= E1000_EECD_DO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	do {
15babd8d4205 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",
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
		eecd &= ~E1000_EECD_DI;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		if (data & mask)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
			eecd |= E1000_EECD_DI;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
		udelay(eeprom->delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
		e1000_raise_ee_clk(hw, &eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
		e1000_lower_ee_clk(hw, &eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
		mask = mask >> 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	} while (mask);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	eecd &= ~E1000_EECD_DI;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
	ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
 * @count: number of bits to shift in
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	u32 eecd;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	u32 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	u16 data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
15babd8d4205 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'
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
	 * always be clear.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
	eecd = er32(EECD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
	data = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
	for (i = 0; i < count; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
		data = data << 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
		e1000_raise_ee_clk(hw, &eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
		eecd = er32(EECD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
		eecd &= ~(E1000_EECD_DI);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
		if (eecd & E1000_EECD_DO)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
			data |= 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
		e1000_lower_ee_clk(hw, &eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	return data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
 * e1000_acquire_eeprom - Prepares EEPROM for access
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
 *
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
	u32 eecd, i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
	DEBUGFUNC("e1000_acquire_eeprom");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
	eecd = er32(EECD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
	/* Request EEPROM Access */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
	if (hw->mac_type > e1000_82544) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
		eecd |= E1000_EECD_REQ;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		eecd = er32(EECD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
		while ((!(eecd & E1000_EECD_GNT)) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
		       (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
			i++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
			udelay(5);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
			eecd = er32(EECD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		if (!(eecd & E1000_EECD_GNT)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
			eecd &= ~E1000_EECD_REQ;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
			ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
			DEBUGOUT("Could not acquire EEPROM grant\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
			return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	/* Setup EEPROM for Read/Write */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
	if (eeprom->type == e1000_eeprom_microwire) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		/* Clear SK and DI */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
		/* Set CS */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
		eecd |= E1000_EECD_CS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
	} else if (eeprom->type == e1000_eeprom_spi) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
		/* Clear SK and CS */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
		udelay(1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
	u32 eecd;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
	eecd = er32(EECD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	if (eeprom->type == e1000_eeprom_microwire) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
		udelay(eeprom->delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
		/* Clock high */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
		eecd |= E1000_EECD_SK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
		udelay(eeprom->delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
		/* Select EEPROM */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
		eecd |= E1000_EECD_CS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
		udelay(eeprom->delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
		/* Clock low */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
		eecd &= ~E1000_EECD_SK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
		udelay(eeprom->delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
	} else if (eeprom->type == e1000_eeprom_spi) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
		/* Toggle CS to flush commands */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
		eecd |= E1000_EECD_CS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
		udelay(eeprom->delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
		eecd &= ~E1000_EECD_CS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
		udelay(eeprom->delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
 * e1000_release_eeprom - drop chip select
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	u32 eecd;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	DEBUGFUNC("e1000_release_eeprom");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	eecd = er32(EECD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	if (hw->eeprom.type == e1000_eeprom_spi) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
		eecd |= E1000_EECD_CS;	/* Pull CS high */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
		eecd &= ~E1000_EECD_SK;	/* Lower SCK */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
		udelay(hw->eeprom.delay_usec);
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
		/* cleanup eeprom */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
		/* CS on Microwire is active-high */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
		/* Rising edge of clock */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
		eecd |= E1000_EECD_SK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
		udelay(hw->eeprom.delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
		/* Falling edge of clock */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
		eecd &= ~E1000_EECD_SK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
		udelay(hw->eeprom.delay_usec);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	/* Stop requesting EEPROM access */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	if (hw->mac_type > e1000_82544) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
		eecd &= ~E1000_EECD_REQ;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
		ew32(EECD, eecd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	u16 retry_count = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	u8 spi_stat_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
	DEBUGFUNC("e1000_spi_eeprom_ready");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
	 * 5 milliseconds, then error out.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	retry_count = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	do {
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
					hw->eeprom.opcode_bits);
15babd8d4205 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);
15babd8d4205 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))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
		udelay(5);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
		retry_count += 5;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
		e1000_standby_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
	} while (retry_count < EEPROM_MAX_RETRY_SPI);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
	 * only 0-5mSec on 5V devices)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
	if (retry_count >= EEPROM_MAX_RETRY_SPI) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
		DEBUGOUT("SPI EEPROM Status error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
		return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
 * @data: word read from the EEPROM
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
 * @words: number of words to read
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	s32 ret;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
	spin_lock(&e1000_eeprom_lock);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
	spin_unlock(&e1000_eeprom_lock);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
	return ret;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
				u16 *data)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
	u32 i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	DEBUGFUNC("e1000_read_eeprom");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
	if (eeprom->word_size == 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
		e1000_init_eeprom_params(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
	 * enough words.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
	if ((offset >= eeprom->word_size)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
	    || (words > eeprom->word_size - offset) || (words == 0)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
		DEBUGOUT2
15babd8d4205 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",
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
		     offset, eeprom->word_size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
		return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
	/* Prepare the EEPROM for bit-bang reading */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
15babd8d4205 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
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
	if (eeprom->type == e1000_eeprom_spi) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
		u16 word_in;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
		u8 read_opcode = EEPROM_READ_OPCODE_SPI;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
		if (e1000_spi_eeprom_ready(hw)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
			e1000_release_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
			return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
		e1000_standby_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
		if ((eeprom->address_bits == 8) && (offset >= 128))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
			read_opcode |= EEPROM_A8_OPCODE_SPI;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
		/* Send the READ command (opcode + addr)  */
15babd8d4205 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);
15babd8d4205 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),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
					eeprom->address_bits);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
		 * starting from any offset. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		for (i = 0; i < words; i++) {
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	} else if (eeprom->type == e1000_eeprom_microwire) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
		for (i = 0; i < words; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
			/* Send the READ command (opcode + addr)  */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
			e1000_shift_out_ee_bits(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
						EEPROM_READ_OPCODE_MICROWIRE,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
						eeprom->opcode_bits);
15babd8d4205 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),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
						eeprom->address_bits);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
			 * of eeprom setup and tear-down. */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
			e1000_standby_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
	/* End this read operation */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
	e1000_release_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
 *
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
 * valid.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
	u16 checksum = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	u16 i, eeprom_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	DEBUGFUNC("e1000_validate_eeprom_checksum");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
15babd8d4205 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++) {
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
			DEBUGOUT("EEPROM Read Error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
			return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
		checksum += eeprom_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
	if (checksum == (u16) EEPROM_SUM)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
	else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
		DEBUGOUT("EEPROM Checksum Invalid\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
 *
15babd8d4205 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.
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
	u16 checksum = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	u16 i, eeprom_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
	DEBUGFUNC("e1000_update_eeprom_checksum");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
15babd8d4205 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++) {
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
			DEBUGOUT("EEPROM Read Error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
			return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
		checksum += eeprom_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
	checksum = (u16) EEPROM_SUM - checksum;
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
		DEBUGOUT("EEPROM Write Error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
		return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
 * @words: number of words to write
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
 *
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
	s32 ret;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	spin_lock(&e1000_eeprom_lock);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
	spin_unlock(&e1000_eeprom_lock);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
	return ret;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
				 u16 *data)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	s32 status = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
	DEBUGFUNC("e1000_write_eeprom");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
	if (eeprom->word_size == 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		e1000_init_eeprom_params(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
	 * enough words.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
	if ((offset >= eeprom->word_size)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
	    || (words > eeprom->word_size - offset) || (words == 0)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		DEBUGOUT("\"words\" parameter out of bounds\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
		return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	/* Prepare the EEPROM for writing  */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
	if (eeprom->type == e1000_eeprom_microwire) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
	} else {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		msleep(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
	/* Done with writing */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	e1000_release_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
	return status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
 * @words: number of words to write
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
				  u16 *data)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	u16 widx = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
	DEBUGFUNC("e1000_write_eeprom_spi");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
	while (widx < words) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
		u8 write_opcode = EEPROM_WRITE_OPCODE_SPI;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
		if (e1000_spi_eeprom_ready(hw))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
			return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
		e1000_standby_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
15babd8d4205 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 )  */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
					eeprom->opcode_bits);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
		e1000_standby_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
		if ((eeprom->address_bits == 8) && (offset >= 128))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
			write_opcode |= EEPROM_A8_OPCODE_SPI;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
15babd8d4205 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) */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
15babd8d4205 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),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
					eeprom->address_bits);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		/* Send the data */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
		while (widx < words) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
			u16 word_out = data[widx];
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
			widx++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
			 */
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
				e1000_standby_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
 * @words: number of words to write
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
					u16 words, u16 *data)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
	u32 eecd;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
	u16 words_written = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
	u16 i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
	DEBUGFUNC("e1000_write_eeprom_microwire");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
	 * EEPROM into write/erase mode.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
	 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
				(u16) (eeprom->opcode_bits + 2));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
15babd8d4205 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));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
	/* Prepare the EEPROM */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
	e1000_standby_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	while (words_written < words) {
15babd8d4205 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) */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
					eeprom->opcode_bits);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
15babd8d4205 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),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
					eeprom->address_bits);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
		/* Send the data */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
		 * the previous command.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
		e1000_standby_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
		for (i = 0; i < 200; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
			eecd = er32(EECD);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
			if (eecd & E1000_EECD_DO)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
			udelay(50);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
		if (i == 200) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
			DEBUGOUT("EEPROM Write did not complete\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
			return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
		/* Recover from write */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		e1000_standby_eeprom(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
		words_written++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
	 * EEPROM out of write/erase mode.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
	 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
				(u16) (eeprom->opcode_bits + 2));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
15babd8d4205 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));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
 * second function of dual function devices
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	u16 offset;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	u16 eeprom_data, i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	DEBUGFUNC("e1000_read_mac_addr");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
		offset = i >> 1;
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
			DEBUGOUT("EEPROM Read Error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
			return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
		}
15babd8d4205 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);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
	case e1000_82546:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
	case e1000_82546_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
			hw->perm_mac_addr[5] ^= 0x01;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
15babd8d4205 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++)
15babd8d4205 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];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
 *
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
	u32 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
	u32 rar_num;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
	DEBUGFUNC("e1000_init_rx_addrs");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
	/* Setup the receive address. */
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
	rar_num = E1000_RAR_ENTRIES;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
	/* Zero out the other 15 receive addresses. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
	DEBUGOUT("Clearing RAR[1-15]\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
	for (i = 1; i < rar_num; i++) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
		E1000_WRITE_FLUSH();
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
 * @mc_addr: the multicast address to hash
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
	u32 hash_value = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
	 * determined by the mc_filter_type setting.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
	switch (hw->mc_filter_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
		/* [0] [1] [2] [3] [4] [5]
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
		 * 01  AA  00  12  34  56
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
		 * LSB                 MSB
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
	case 0:
15babd8d4205 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 */
15babd8d4205 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));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
	case 1:
15babd8d4205 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 */
15babd8d4205 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));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
	case 2:
15babd8d4205 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 */
15babd8d4205 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));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
	case 3:
15babd8d4205 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 */
15babd8d4205 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));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
	hash_value &= 0xFFF;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
	return hash_value;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
 * @index: Receive address register to write
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
	u32 rar_low, rar_high;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
	 */
15babd8d4205 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) |
15babd8d4205 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));
15babd8d4205 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));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
	 * unit hang.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
	 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
	 * Description:
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	 * on our merry way.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
		/* Indicate to hardware the Address is Valid. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
		rar_high |= E1000_RAH_AV;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
	E1000_WRITE_FLUSH();
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
	u32 temp;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
15babd8d4205 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)) {
15babd8d4205 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));
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
		E1000_WRITE_FLUSH();
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
	} else {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	u32 offset;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
	u32 vfta_value = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
	u32 vfta_offset = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	u32 vfta_bit_in_reg = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
15babd8d4205 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++) {
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
		 * manageability unit */
15babd8d4205 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;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
	u32 ledctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
	const u32 ledctl_mask = 0x000000FF;
15babd8d4205 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;
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
	u16 eeprom_data, i, temp;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
	const u16 led_mask = 0x0F;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
	DEBUGFUNC("e1000_id_led_init");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
	if (hw->mac_type < e1000_82540) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
		/* Nothing to do */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
	ledctl = er32(LEDCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
	hw->ledctl_default = ledctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
	hw->ledctl_mode1 = hw->ledctl_default;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
	hw->ledctl_mode2 = hw->ledctl_default;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
		DEBUGOUT("EEPROM Read Error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
		return -E1000_ERR_EEPROM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
	if ((eeprom_data == ID_LED_RESERVED_0000) ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	    (eeprom_data == ID_LED_RESERVED_FFFF)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
		eeprom_data = ID_LED_DEFAULT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	for (i = 0; i < 4; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		temp = (eeprom_data >> (i << 2)) & led_mask;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
		switch (temp) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
		case ID_LED_ON1_DEF2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
		case ID_LED_ON1_ON2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
		case ID_LED_ON1_OFF2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
			hw->ledctl_mode1 |= ledctl_on << (i << 3);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
		case ID_LED_OFF1_DEF2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
		case ID_LED_OFF1_ON2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
		case ID_LED_OFF1_OFF2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
			hw->ledctl_mode1 |= ledctl_off << (i << 3);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
		default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
			/* Do nothing */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
		switch (temp) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
		case ID_LED_DEF1_ON2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
		case ID_LED_ON1_ON2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
		case ID_LED_OFF1_ON2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
			hw->ledctl_mode2 |= ledctl_on << (i << 3);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
		case ID_LED_DEF1_OFF2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
		case ID_LED_ON1_OFF2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		case ID_LED_OFF1_OFF2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
			hw->ledctl_mode2 |= ledctl_off << (i << 3);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
		default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
			/* Do nothing */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
 * e1000_setup_led
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
 *
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
	u32 ledctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
	s32 ret_val = E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	DEBUGFUNC("e1000_setup_led");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
	case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
	case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
	case e1000_82543:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
	case e1000_82544:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
		/* No setup necessary */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
	case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
	case e1000_82547:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
	case e1000_82541_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
	case e1000_82547_rev_2:
15babd8d4205 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) */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
					     &hw->phy_spd_default);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
			return ret_val;
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
					      (u16) (hw->phy_spd_default &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
						     ~IGP01E1000_GMII_SPD));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
		/* Fall Through */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
	default:
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
			ledctl = er32(LEDCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
			/* Save current LEDCTL settings */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
			hw->ledctl_default = ledctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
			/* Turn off LED0 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
			ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
				    E1000_LEDCTL_LED0_BLINK |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
				    E1000_LEDCTL_LED0_MODE_MASK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
			ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
				   E1000_LEDCTL_LED0_MODE_SHIFT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
			ew32(LEDCTL, ledctl);
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
			ew32(LEDCTL, hw->ledctl_mode1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	s32 ret_val = E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
	DEBUGFUNC("e1000_cleanup_led");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
	case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
	case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
	case e1000_82543:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	case e1000_82544:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
		/* No cleanup necessary */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
	case e1000_82547:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
	case e1000_82541_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
	case e1000_82547_rev_2:
15babd8d4205 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) */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
					      hw->phy_spd_default);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		/* Fall Through */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
		/* Restore LEDCTL settings */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
		ew32(LEDCTL, hw->ledctl_default);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
	u32 ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
	DEBUGFUNC("e1000_led_on");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
	case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	case e1000_82543:
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
		ctrl |= E1000_CTRL_SWDPIN0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
		ctrl |= E1000_CTRL_SWDPIO0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	case e1000_82544:
15babd8d4205 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) {
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
			ctrl |= E1000_CTRL_SWDPIN0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
			ctrl |= E1000_CTRL_SWDPIO0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
		} else {
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
			ctrl &= ~E1000_CTRL_SWDPIN0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
			ctrl |= E1000_CTRL_SWDPIO0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
	default:
15babd8d4205 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) {
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
			ctrl &= ~E1000_CTRL_SWDPIN0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
			ctrl |= E1000_CTRL_SWDPIO0;
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
			ew32(LEDCTL, hw->ledctl_mode2);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
			return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
	u32 ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	DEBUGFUNC("e1000_led_off");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
	case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
	case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
	case e1000_82543:
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
		ctrl &= ~E1000_CTRL_SWDPIN0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
		ctrl |= E1000_CTRL_SWDPIO0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
	case e1000_82544:
15babd8d4205 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) {
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
			ctrl &= ~E1000_CTRL_SWDPIN0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
			ctrl |= E1000_CTRL_SWDPIO0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
		} else {
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
			ctrl |= E1000_CTRL_SWDPIN0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
			ctrl |= E1000_CTRL_SWDPIO0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
	default:
15babd8d4205 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) {
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
			ctrl |= E1000_CTRL_SWDPIN0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
			ctrl |= E1000_CTRL_SWDPIO0;
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
			ew32(LEDCTL, hw->ledctl_mode1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
			return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	volatile u32 temp;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	temp = er32(CRCERRS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	temp = er32(SYMERRS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	temp = er32(MPC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	temp = er32(SCC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	temp = er32(ECOL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
	temp = er32(MCC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
	temp = er32(LATECOL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
	temp = er32(COLC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
	temp = er32(DC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
	temp = er32(SEC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
	temp = er32(RLEC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
	temp = er32(XONRXC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
	temp = er32(XONTXC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	temp = er32(XOFFRXC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
	temp = er32(XOFFTXC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
	temp = er32(FCRUC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
	temp = er32(PRC64);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	temp = er32(PRC127);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
	temp = er32(PRC255);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
	temp = er32(PRC511);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
	temp = er32(PRC1023);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	temp = er32(PRC1522);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
	temp = er32(GPRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
	temp = er32(BPRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	temp = er32(MPRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
	temp = er32(GPTC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
	temp = er32(GORCL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	temp = er32(GORCH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
	temp = er32(GOTCL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
	temp = er32(GOTCH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	temp = er32(RNBC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
	temp = er32(RUC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
	temp = er32(RFC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	temp = er32(ROC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
	temp = er32(RJC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
	temp = er32(TORL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	temp = er32(TORH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	temp = er32(TOTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	temp = er32(TOTH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
	temp = er32(TPR);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	temp = er32(TPT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	temp = er32(PTC64);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	temp = er32(PTC127);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	temp = er32(PTC255);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
	temp = er32(PTC511);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	temp = er32(PTC1023);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
	temp = er32(PTC1522);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
	temp = er32(MPTC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
	temp = er32(BPTC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	if (hw->mac_type < e1000_82543)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	temp = er32(ALGNERRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	temp = er32(RXERRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	temp = er32(TNCRS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	temp = er32(CEXTERR);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
	temp = er32(TSCTC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	temp = er32(TSCTFC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
	if (hw->mac_type <= e1000_82544)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	temp = er32(MGTPRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	temp = er32(MGTPDC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	temp = er32(MGTPTC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
 *
15babd8d4205 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
15babd8d4205 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->
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
 * before calling this function.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
	DEBUGFUNC("e1000_reset_adaptive");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	if (hw->adaptive_ifs) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
		if (!hw->ifs_params_forced) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
			hw->current_ifs_val = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
			hw->ifs_min_val = IFS_MIN;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
			hw->ifs_max_val = IFS_MAX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
			hw->ifs_step_size = IFS_STEP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
			hw->ifs_ratio = IFS_RATIO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		hw->in_ifs_mode = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
		ew32(AIT, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
		DEBUGOUT("Not in Adaptive IFS mode!\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
 * e1000_update_adaptive - update adaptive IFS
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
 * the ratio of transmits to collisions.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
	DEBUGFUNC("e1000_update_adaptive");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
	if (hw->adaptive_ifs) {
15babd8d4205 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) {
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
				hw->in_ifs_mode = true;
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
					if (hw->current_ifs_val == 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
						hw->current_ifs_val =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
						    hw->ifs_min_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
					else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
						hw->current_ifs_val +=
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
						    hw->ifs_step_size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
					ew32(AIT, hw->current_ifs_val);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
				}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
			if (hw->in_ifs_mode
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
			    && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
				hw->current_ifs_val = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
				hw->in_ifs_mode = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
				ew32(AIT, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
		DEBUGOUT("Not in Adaptive IFS mode!\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
 * e1000_tbi_adjust_stats
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
			    u32 frame_len, u8 *mac_addr)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
	u64 carry_bit;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	/* First adjust the frame length. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
	frame_len--;
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
	 * the packet as a good packet
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
	 */
15babd8d4205 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.    */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	stats->crcerrs--;
15babd8d4205 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.    */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	stats->gprc++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	/* Adjust the Good Octets received counters             */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	carry_bit = 0x80000000 & stats->gorcl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	stats->gorcl += frame_len;
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	 * Received Count) was one before the addition,
15babd8d4205 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,
15babd8d4205 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).
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	 * 64-bit integers.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
	if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
		stats->gorch++;
15babd8d4205 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,
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
	 * a broadcast frame.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	 */
15babd8d4205 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))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
		/* Broadcast packet */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
		stats->bprc++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
	else if (*mac_addr & 0x01)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
		/* Multicast packet */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
		stats->mprc++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	if (frame_len == hw->max_frame_size) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
		 * oversize frames.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
		if (stats->roc > 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
			stats->roc--;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	if (frame_len == 64) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
		stats->prc64++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
		stats->prc127--;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	} else if (frame_len == 127) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
		stats->prc127++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
		stats->prc255--;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	} else if (frame_len == 255) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
		stats->prc255++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
		stats->prc511--;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
	} else if (frame_len == 511) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
		stats->prc511++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
		stats->prc1023--;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
	} else if (frame_len == 1023) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
		stats->prc1023++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
		stats->prc1522--;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
	} else if (frame_len == 1522) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
		stats->prc1522++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
 * e1000_get_bus_info
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	u32 status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
	case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
		hw->bus_type = e1000_bus_type_pci;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
		hw->bus_speed = e1000_bus_speed_unknown;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
		hw->bus_width = e1000_bus_width_unknown;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
		status = er32(STATUS);
15babd8d4205 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) ?
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
15babd8d4205 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) {
15babd8d4205 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) ?
15babd8d4205 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;
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
			hw->bus_speed = (status & E1000_STATUS_PCI66) ?
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
			switch (status & E1000_STATUS_PCIX_SPEED) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
			case E1000_STATUS_PCIX_SPEED_66:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
				hw->bus_speed = e1000_bus_speed_66;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
			case E1000_STATUS_PCIX_SPEED_100:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
				hw->bus_speed = e1000_bus_speed_100;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
			case E1000_STATUS_PCIX_SPEED_133:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
				hw->bus_speed = e1000_bus_speed_133;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
			default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
				hw->bus_speed = e1000_bus_speed_reserved;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
		hw->bus_width = (status & E1000_STATUS_BUS64) ?
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
 * e1000_write_reg_io
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
 * @offset: offset to write to
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
 * @value: value to write
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
 *
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
	unsigned long io_addr = hw->io_base;
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
	e1000_io_write(hw, io_addr, offset);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	e1000_io_write(hw, io_data, value);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
/**
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
 * @min_length: The estimated minimum length
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
 * @max_length: The estimated maximum length
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
 * returns: - E1000_ERR_XXX
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
 *            E1000_SUCCESS
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
 *
15babd8d4205 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).
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
 * register to the minimum and maximum range.
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
				  u16 *max_length)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
	u16 agc_value = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
	u16 i, phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	u16 cable_length;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
	DEBUGFUNC("e1000_get_cable_length");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
	*min_length = *max_length = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
	if (hw->phy_type == e1000_phy_m88) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
					     &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
			return ret_val;
15babd8d4205 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) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
		    M88E1000_PSSR_CABLE_LENGTH_SHIFT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
		/* Convert the enum value to ranged values */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
		switch (cable_length) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
		case e1000_cable_length_50:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
			*min_length = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
			*max_length = e1000_igp_cable_length_50;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
		case e1000_cable_length_50_80:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
			*min_length = e1000_igp_cable_length_50;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
			*max_length = e1000_igp_cable_length_80;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
		case e1000_cable_length_80_110:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
			*min_length = e1000_igp_cable_length_80;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
			*max_length = e1000_igp_cable_length_110;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
		case e1000_cable_length_110_140:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
			*min_length = e1000_igp_cable_length_110;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
			*max_length = e1000_igp_cable_length_140;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
		case e1000_cable_length_140:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
			*min_length = e1000_igp_cable_length_140;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
			*max_length = e1000_igp_cable_length_170;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
		default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
			return -E1000_ERR_PHY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
		}
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
		u16 cur_agc_value;
15babd8d4205 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;
15babd8d4205 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] =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
		    { IGP01E1000_PHY_AGC_A,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
			IGP01E1000_PHY_AGC_B,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
			IGP01E1000_PHY_AGC_C,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
			IGP01E1000_PHY_AGC_D
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
		};
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
		/* Read the AGC registers for all channels */
15babd8d4205 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++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
			/* Value bound check. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
			if ((cur_agc_value >=
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
			     IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
			    || (cur_agc_value == 0))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
				return -E1000_ERR_PHY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
			agc_value += cur_agc_value;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
			/* Update minimal AGC value. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
			if (min_agc_value > cur_agc_value)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
				min_agc_value = cur_agc_value;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
		if (agc_value <
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
			agc_value -= min_agc_value;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
			agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
		} else {
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
			agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
		/* Set the range of the calculated length. */
15babd8d4205 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] -
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
				IGP01E1000_AGC_RANGE) > 0) ?
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
		    (e1000_igp_cable_length_table[agc_value] -
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
		     IGP01E1000_AGC_RANGE) : 0;
15babd8d4205 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] +
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
		    IGP01E1000_AGC_RANGE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
 * e1000_check_polarity - Check the cable polarity
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
 *                               1 - Polarity is reversed.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
 * returns: - E1000_ERR_XXX
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
 *            E1000_SUCCESS
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
 *
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
 * IGP01E1000_PHY_PCS_INIT_REG.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
				e1000_rev_polarity *polarity)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
	DEBUGFUNC("e1000_check_polarity");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
	if (hw->phy_type == e1000_phy_m88) {
15babd8d4205 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. */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
					     &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
		*polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
			     M88E1000_PSSR_REV_POLARITY_SHIFT) ?
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
15babd8d4205 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) {
15babd8d4205 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 */
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
					     &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
		 * find the polarity status */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
		if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
		    IGP01E1000_PSSR_SPEED_1000MBPS) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
			/* Read the GIG initialization PCS register (0x00B4) */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
					       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
			/* Check the polarity bits */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
			*polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
			    e1000_rev_polarity_reversed :
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
			    e1000_rev_polarity_normal;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
		} else {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
			 * 100 Mbps this bit is always 0) */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
			*polarity =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
			    (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
			    e1000_rev_polarity_reversed :
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
			    e1000_rev_polarity_normal;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
 * e1000_check_downshift - Check if Downshift occurred
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
 * @downshift: output parameter : 0 - No Downshift occurred.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
 *                                1 - Downshift occurred.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
 * returns: - E1000_ERR_XXX
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
 *            E1000_SUCCESS
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
 *
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
 * read it immediately after link is established.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
	DEBUGFUNC("e1000_check_downshift");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
	if (hw->phy_type == e1000_phy_igp) {
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
					     &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
		hw->speed_downgraded =
15babd8d4205 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;
15babd8d4205 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) {
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
					     &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
15babd8d4205 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) >>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
		    M88E1000_PSSR_DOWNSHIFT_SHIFT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
 * e1000_config_dsp_after_link_change
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
 *            E1000_SUCCESS at any other case.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
 *
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
	s32 ret_val;
15babd8d4205 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;
15babd8d4205 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] =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
	    { IGP01E1000_PHY_AGC_PARAM_A,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
		IGP01E1000_PHY_AGC_PARAM_B,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
		IGP01E1000_PHY_AGC_PARAM_C,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
		IGP01E1000_PHY_AGC_PARAM_D
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
	};
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
	u16 min_length, max_length;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
	DEBUGFUNC("e1000_config_dsp_after_link_change");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
	if (hw->phy_type != e1000_phy_igp)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
	if (link_up) {
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
		if (ret_val) {
15babd8d4205 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");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
		if (speed == SPEED_1000) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
			ret_val =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
			    e1000_get_cable_length(hw, &min_length,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
						   &max_length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
			    && min_length >= e1000_igp_cable_length_50) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
15babd8d4205 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++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
					ret_val =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
					    e1000_read_phy_reg(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
							       dsp_reg_array[i],
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
							       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
					if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
						return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
					phy_data &=
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
					    ~IGP01E1000_PHY_EDAC_MU_INDEX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
					ret_val =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
					    e1000_write_phy_reg(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
								dsp_reg_array
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
								[i], phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
					if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
						return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
				}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
				hw->dsp_config_state =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
				    e1000_dsp_config_activated;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
			    && (min_length < e1000_igp_cable_length_50)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
				u16 ffe_idle_err_timeout =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
				    FFE_IDLE_ERR_COUNT_TIMEOUT_20;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
				u32 idle_errs = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
				/* clear previous idle error counts */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
				ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
						       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
				if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
					return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
15babd8d4205 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++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
					udelay(1000);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
					ret_val =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
					    e1000_read_phy_reg(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
							       PHY_1000T_STATUS,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
							       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
					if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
						return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
					idle_errs +=
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
					    (phy_data &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
					     SR_1000T_IDLE_ERROR_CNT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
					if (idle_errs >
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
					    SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
					{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
						hw->ffe_config_state =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
						    e1000_ffe_config_active;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
						ret_val =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
						    e1000_write_phy_reg(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
									IGP01E1000_PHY_DSP_FFE,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
									IGP01E1000_PHY_DSP_FFE_CM_CP);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
						if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
							return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
						break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
					}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
					if (idle_errs)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
						ffe_idle_err_timeout =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
						    FFE_IDLE_ERR_COUNT_TIMEOUT_100;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
				}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
	} else {
15babd8d4205 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) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
			 * the end of the routines. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
			/* Disable the PHY transmitter */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
			mdelay(20);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
						      IGP01E1000_IEEE_FORCE_GIGA);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
				return ret_val;
15babd8d4205 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++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
				ret_val =
15babd8d4205 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],
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
						       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
				if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
					return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
				phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
				ret_val =
15babd8d4205 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],
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
							phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
				if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
					return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
						      IGP01E1000_IEEE_RESTART_AUTONEG);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
			mdelay(20);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
			/* Now enable the transmitter */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
15babd8d4205 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) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
			 * the end of the routines. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
			/* Disable the PHY transmitter */
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
			mdelay(20);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
						      IGP01E1000_IEEE_FORCE_GIGA);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
						IGP01E1000_PHY_DSP_FFE_DEFAULT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
						      IGP01E1000_IEEE_RESTART_AUTONEG);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
			mdelay(20);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
			/* Now enable the transmitter */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
			ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
15babd8d4205 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;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
 *
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
 *  1. Do a PHY soft reset
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
 *  2. Restart auto-negotiation or force link.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
	u16 eeprom_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
	DEBUGFUNC("e1000_set_phy_mode");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
15babd8d4205 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) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
	    (hw->media_type == e1000_media_type_copper)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
		ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
				      &eeprom_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
		if (ret_val) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
		if ((eeprom_data != EEPROM_RESERVED_WORD) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
		    (eeprom_data & EEPROM_PHY_CLASS_A)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
						0x000B);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
						0x8104);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
			hw->phy_reset_disable = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
 *
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 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
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
 *            E1000_SUCCESS at any other case.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
	DEBUGFUNC("e1000_set_d3_lplu_state");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
	if (hw->phy_type != e1000_phy_igp)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
	 * Dx transitions and states */
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
	    || hw->mac_type == e1000_82547_rev_2) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
		ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
	if (!active) {
15babd8d4205 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 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
		    hw->mac_type == e1000_82547_rev_2) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
			phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
						phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
15babd8d4205 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
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
		 * maintained. */
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
					       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
			phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
						phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
				return ret_val;
15babd8d4205 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) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
					       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
						phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
		}
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
		   || (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
		   || (hw->autoneg_advertised ==
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
		       AUTONEG_ADVERTISE_10_100_ALL)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
15babd8d4205 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 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
		    hw->mac_type == e1000_82547_rev_2) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
			phy_data |= IGP01E1000_GMII_FLEX_SPD;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
			ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
						phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
			if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
				return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
		ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
				       &phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
		phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
		ret_val =
15babd8d4205 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,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
					phy_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
 * e1000_set_vco_speed
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
 *
15babd8d4205 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.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
	u16 default_page = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
	u16 phy_data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
	DEBUGFUNC("e1000_set_vco_speed");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
	case e1000_82545_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
	case e1000_82546_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
		return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
	ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
	phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
	phy_data |= M88E1000_PHY_VCO_REG_BIT11;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
	ret_val =
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
/**
15babd8d4205 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
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
 *
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
 * returns: - true/false
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
	u32 manc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
	if (hw->asf_firmware_present) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
		manc = er32(MANC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
		if (!(manc & E1000_MANC_RCV_TCO_EN) ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
		    !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
			return false;
15babd8d4205 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))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
			return true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
	return false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
	s32 ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
	u16 mii_status_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
	u16 i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
15babd8d4205 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. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
	/* Disable the transmitter on the PHY */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
		return ret_val;
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
15babd8d4205 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. */
15babd8d4205 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--) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
		 * to be clear.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
		mdelay(100);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
	mdelay(1000);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
15babd8d4205 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 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
	mdelay(50);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
	mdelay(50);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
	mdelay(50);
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
		return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
15babd8d4205 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. */
15babd8d4205 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--) {
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
		 * to be set.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
15babd8d4205 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);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
		if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
			return ret_val;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
		mdelay(100);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
 * e1000_get_auto_rd_done
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
 * Check for EEPROM Auto Read bit done.
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
 *            E1000_SUCCESS at any other case.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
	DEBUGFUNC("e1000_get_auto_rd_done");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
	msleep(5);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
 * e1000_get_phy_cfg_done
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
 * Checks if the PHY configuration is done
15babd8d4205 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
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
 *            E1000_SUCCESS at any other case.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
 */
15babd8d4205 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)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
	DEBUGFUNC("e1000_get_phy_cfg_done");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
	mdelay(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
}