devices/e1000/e1000_hw-2.6.35-ethercat.c
author Gavin Lambert <gavinl@compacsort.com>
Tue, 14 Apr 2015 09:33:24 -0400
changeset 2618 3affe9cd0b66
parent 2282 9c0710c38627
permissions -rw-r--r--
Ignore NXIO error otherwise this causes spam if network is empty or refclk not
selected yet, and syncing refclk time to master.
2282
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
/* e1000_hw.c
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
 * Shared functions for accessing and configuring the MAC
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include "e1000-2.6.35-ethercat.h"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
static s32 e1000_check_downshift(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static s32 e1000_check_polarity(struct e1000_hw *hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
				e1000_rev_polarity *polarity);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
static void e1000_clear_vfta(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
					      bool link_up);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
static s32 e1000_detect_gig_phy(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
				  u16 *max_length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
static s32 e1000_id_led_init(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
static void e1000_init_rx_addrs(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
				  struct e1000_phy_info *phy_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
				  struct e1000_phy_info *phy_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
static s32 e1000_wait_autoneg(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
static s32 e1000_set_phy_type(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
static void e1000_phy_init_script(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
static s32 e1000_setup_copper_link(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
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);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
				  u16 words, u16 *data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
					u16 words, u16 *data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
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);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
				  u16 phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
				 u16 *phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
static s32 e1000_acquire_eeprom(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
static void e1000_release_eeprom(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
static void e1000_standby_eeprom(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
static s32 e1000_set_vco_speed(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
static s32 e1000_set_phy_mode(struct e1000_hw *hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
				u16 *data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
				 u16 *data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
/* IGP cable length table */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
static const
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
u16 e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = {
9c0710c38627 Added e1000 driver for 2.6.35.
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,
9c0710c38627 Added e1000 driver for 2.6.35.
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,
9c0710c38627 Added e1000 driver for 2.6.35.
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,
9c0710c38627 Added e1000 driver for 2.6.35.
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,
9c0710c38627 Added e1000 driver for 2.6.35.
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,
9c0710c38627 Added e1000 driver for 2.6.35.
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,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	    100,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	    110, 110,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	    120, 120
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
};
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static DEFINE_SPINLOCK(e1000_eeprom_lock);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
 * e1000_set_phy_type - Set the phy type member in the hw struct.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static s32 e1000_set_phy_type(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	e_dbg("e1000_set_phy_type");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	if (hw->mac_type == e1000_undefined)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
		return -E1000_ERR_PHY_TYPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	switch (hw->phy_id) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	case M88E1000_E_PHY_ID:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	case M88E1000_I_PHY_ID:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	case M88E1011_I_PHY_ID:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	case M88E1111_I_PHY_ID:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
		hw->phy_type = e1000_phy_m88;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	case IGP01E1000_I_PHY_ID:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
		if (hw->mac_type == e1000_82541 ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
		    hw->mac_type == e1000_82541_rev_2 ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
		    hw->mac_type == e1000_82547 ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
		    hw->mac_type == e1000_82547_rev_2) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
			hw->phy_type = e1000_phy_igp;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
		/* Should never have loaded on this device */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
		hw->phy_type = e1000_phy_undefined;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
		return -E1000_ERR_PHY_TYPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
 * e1000_phy_init_script - IGP phy init script - initializes the GbE PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static void e1000_phy_init_script(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
	u32 ret_val __attribute__ ((unused));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
	u16 phy_saved_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
	e_dbg("e1000_phy_init_script");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	if (hw->phy_init_script) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
		msleep(20);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
		/* Save off the current value of register 0x2F5B to be restored at
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
		 * the end of this routine. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
		ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
		/* Disabled the PHY transmitter */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
		e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
		msleep(20);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
		e1000_write_phy_reg(hw, 0x0000, 0x0140);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
		msleep(5);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
		case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
		case e1000_82547:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
			e1000_write_phy_reg(hw, 0x1F95, 0x0001);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
			e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
			e1000_write_phy_reg(hw, 0x1F79, 0x0018);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
			e1000_write_phy_reg(hw, 0x1F30, 0x1600);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
			e1000_write_phy_reg(hw, 0x1F31, 0x0014);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
			e1000_write_phy_reg(hw, 0x1F32, 0x161C);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
			e1000_write_phy_reg(hw, 0x1F94, 0x0003);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
			e1000_write_phy_reg(hw, 0x1F96, 0x003F);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
			e1000_write_phy_reg(hw, 0x2010, 0x0008);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
		case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
		case e1000_82547_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
			e1000_write_phy_reg(hw, 0x1F73, 0x0099);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
		default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
		e1000_write_phy_reg(hw, 0x0000, 0x3300);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
		msleep(20);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
		/* Now enable the transmitter */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
		e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		if (hw->mac_type == e1000_82547) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
			u16 fused, fine, coarse;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
			/* Move to analog registers page */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
			e1000_read_phy_reg(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
					   IGP01E1000_ANALOG_SPARE_FUSE_STATUS,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
					   &fused);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
			if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
				e1000_read_phy_reg(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
						   IGP01E1000_ANALOG_FUSE_STATUS,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
						   &fused);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
				fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
				coarse =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
				    fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
				if (coarse >
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
				    IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
					coarse -=
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
					    IGP01E1000_ANALOG_FUSE_COARSE_10;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
					fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
				} else if (coarse ==
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
					   IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
					fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
				fused =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
				    (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
				    (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
				    (coarse &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
				     IGP01E1000_ANALOG_FUSE_COARSE_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
				e1000_write_phy_reg(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
						    IGP01E1000_ANALOG_FUSE_CONTROL,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
						    fused);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
				e1000_write_phy_reg(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
						    IGP01E1000_ANALOG_FUSE_BYPASS,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
						    IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
 * e1000_set_mac_type - Set the mac type member in the hw struct.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
s32 e1000_set_mac_type(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	e_dbg("e1000_set_mac_type");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	switch (hw->device_id) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	case E1000_DEV_ID_82542:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
		switch (hw->revision_id) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
		case E1000_82542_2_0_REV_ID:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
			hw->mac_type = e1000_82542_rev2_0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
		case E1000_82542_2_1_REV_ID:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
			hw->mac_type = e1000_82542_rev2_1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
		default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
			/* Invalid 82542 revision ID */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
			return -E1000_ERR_MAC_TYPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	case E1000_DEV_ID_82543GC_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	case E1000_DEV_ID_82543GC_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
		hw->mac_type = e1000_82543;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	case E1000_DEV_ID_82544EI_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	case E1000_DEV_ID_82544EI_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	case E1000_DEV_ID_82544GC_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	case E1000_DEV_ID_82544GC_LOM:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
		hw->mac_type = e1000_82544;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	case E1000_DEV_ID_82540EM:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	case E1000_DEV_ID_82540EM_LOM:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	case E1000_DEV_ID_82540EP:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	case E1000_DEV_ID_82540EP_LOM:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	case E1000_DEV_ID_82540EP_LP:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		hw->mac_type = e1000_82540;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	case E1000_DEV_ID_82545EM_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	case E1000_DEV_ID_82545EM_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
		hw->mac_type = e1000_82545;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	case E1000_DEV_ID_82545GM_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	case E1000_DEV_ID_82545GM_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	case E1000_DEV_ID_82545GM_SERDES:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
		hw->mac_type = e1000_82545_rev_3;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	case E1000_DEV_ID_82546EB_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	case E1000_DEV_ID_82546EB_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
		hw->mac_type = e1000_82546;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	case E1000_DEV_ID_82546GB_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	case E1000_DEV_ID_82546GB_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	case E1000_DEV_ID_82546GB_SERDES:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	case E1000_DEV_ID_82546GB_PCIE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	case E1000_DEV_ID_82546GB_QUAD_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
		hw->mac_type = e1000_82546_rev_3;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	case E1000_DEV_ID_82541EI:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	case E1000_DEV_ID_82541EI_MOBILE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	case E1000_DEV_ID_82541ER_LOM:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		hw->mac_type = e1000_82541;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
	case E1000_DEV_ID_82541ER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	case E1000_DEV_ID_82541GI:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	case E1000_DEV_ID_82541GI_LF:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	case E1000_DEV_ID_82541GI_MOBILE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		hw->mac_type = e1000_82541_rev_2;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	case E1000_DEV_ID_82547EI:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	case E1000_DEV_ID_82547EI_MOBILE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		hw->mac_type = e1000_82547;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	case E1000_DEV_ID_82547GI:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		hw->mac_type = e1000_82547_rev_2;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
		/* Should never have loaded on this device */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
		return -E1000_ERR_MAC_TYPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
	case e1000_82547:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	case e1000_82547_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		hw->asf_firmware_present = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	/* The 82543 chip does not count tx_carrier_errors properly in
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	 * FD mode
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	if (hw->mac_type == e1000_82543)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		hw->bad_tx_carr_stats_fd = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	if (hw->mac_type > e1000_82544)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		hw->has_smbus = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
 * e1000_set_media_type - Set media type and TBI compatibility.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
void e1000_set_media_type(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	u32 status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
	e_dbg("e1000_set_media_type");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
	if (hw->mac_type != e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
		/* tbi_compatibility is only valid on 82543 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
		hw->tbi_compatibility_en = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	switch (hw->device_id) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	case E1000_DEV_ID_82545GM_SERDES:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	case E1000_DEV_ID_82546GB_SERDES:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
		hw->media_type = e1000_media_type_internal_serdes;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
		case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
		case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
			hw->media_type = e1000_media_type_fiber;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
		default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
			status = er32(STATUS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
			if (status & E1000_STATUS_TBIMODE) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
				hw->media_type = e1000_media_type_fiber;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
				/* tbi_compatibility not valid on fiber */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
				hw->tbi_compatibility_en = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
			} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
				hw->media_type = e1000_media_type_copper;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
 * e1000_reset_hw: reset the hardware completely
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
 * Reset the transmit and receive units; mask and clear all interrupts.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
s32 e1000_reset_hw(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	u32 ctrl_ext;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	u32 icr __attribute__ ((unused));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	u32 manc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	u32 led_ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
	e_dbg("e1000_reset_hw");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	/* For 82542 (rev 2.0), disable MWI before issuing a device reset */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	if (hw->mac_type == e1000_82542_rev2_0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
		e_dbg("Disabling MWI on 82542 rev 2.0\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
		e1000_pci_clear_mwi(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	/* Clear interrupt mask to stop board from generating interrupts */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	e_dbg("Masking off all interrupts\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	ew32(IMC, 0xffffffff);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	/* Disable the Transmit and Receive units.  Then delay to allow
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	 * any pending transactions to complete before we hit the MAC with
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	 * the global reset.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	ew32(RCTL, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	ew32(TCTL, E1000_TCTL_PSP);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	/* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	hw->tbi_compatibility_on = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
	/* Delay to allow any outstanding PCI transactions to complete before
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	 * resetting the device
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	msleep(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	/* Must reset the PHY before resetting the MAC */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
		ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		msleep(5);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
	/* Issue a global reset to the MAC.  This will reset the chip's
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	 * transmit, receive, DMA, and link units.  It will not effect
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	 * the current PCI configuration.  The global reset bit is self-
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	 * clearing, and should clear within a microsecond.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	e_dbg("Issuing a global reset to MAC\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	case e1000_82540:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	case e1000_82545:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	case e1000_82546:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
		/* These controllers can't ack the 64-bit write when issuing the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		 * reset, so use IO-mapping as a workaround to issue the reset */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
		E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	case e1000_82545_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	case e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		/* Reset is performed on a shadow of the control register */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		ew32(CTRL_DUP, (ctrl | E1000_CTRL_RST));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		ew32(CTRL, (ctrl | E1000_CTRL_RST));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	/* After MAC reset, force reload of EEPROM to restore power-on settings to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	 * device.  Later controllers reload the EEPROM automatically, so just wait
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	 * for reload to complete.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
	case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	case e1000_82543:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		/* Wait for reset to complete */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
		udelay(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		ctrl_ext = er32(CTRL_EXT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
		ctrl_ext |= E1000_CTRL_EXT_EE_RST;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		ew32(CTRL_EXT, ctrl_ext);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
		/* Wait for EEPROM reload */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
		msleep(2);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	case e1000_82547:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	case e1000_82547_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
		/* Wait for EEPROM reload */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		msleep(20);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		/* Auto read done will delay 5ms or poll based on mac type */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		ret_val = e1000_get_auto_rd_done(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	/* Disable HW ARPs on ASF enabled adapters */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	if (hw->mac_type >= e1000_82540) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
		manc = er32(MANC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		manc &= ~(E1000_MANC_ARP_EN);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		ew32(MANC, manc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
		e1000_phy_init_script(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		/* Configure activity LED after PHY reset */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		led_ctrl = er32(LEDCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
		ew32(LEDCTL, led_ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	/* Clear interrupt mask to stop board from generating interrupts */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	e_dbg("Masking off all interrupts\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	ew32(IMC, 0xffffffff);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	/* Clear any pending interrupt events. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	icr = er32(ICR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	/* If MWI was previously enabled, reenable it. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	if (hw->mac_type == e1000_82542_rev2_0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
			e1000_pci_set_mwi(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
 * e1000_init_hw: Performs basic configuration of the adapter.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
 * Assumes that the controller has previously been reset and is in a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
 * post-reset uninitialized state. Initializes the receive address registers,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
 * multicast table, and VLAN filter table. Calls routines to setup link
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
 * configuration and flow control settings. Clears all on-chip counters. Leaves
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
 * the transmit and receive units disabled and uninitialized.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
s32 e1000_init_hw(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	u32 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	u32 mta_size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	u32 ctrl_ext;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	e_dbg("e1000_init_hw");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	/* Initialize Identification LED */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	ret_val = e1000_id_led_init(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		e_dbg("Error Initializing Identification LED\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	/* Set the media type and TBI compatibility */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	e1000_set_media_type(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	/* Disabling VLAN filtering. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	e_dbg("Initializing the IEEE VLAN\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	if (hw->mac_type < e1000_82545_rev_3)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
		ew32(VET, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	e1000_clear_vfta(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
	if (hw->mac_type == e1000_82542_rev2_0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
		e_dbg("Disabling MWI on 82542 rev 2.0\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
		e1000_pci_clear_mwi(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		ew32(RCTL, E1000_RCTL_RST);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
		msleep(5);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	/* Setup the receive address. This involves initializing all of the Receive
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	 * Address Registers (RARs 0 - 15).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	e1000_init_rx_addrs(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	if (hw->mac_type == e1000_82542_rev2_0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		ew32(RCTL, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		msleep(1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
			e1000_pci_set_mwi(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	/* Zero out the Multicast HASH table */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	e_dbg("Zeroing the MTA\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	mta_size = E1000_MC_TBL_SIZE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	for (i = 0; i < mta_size; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		/* use write flush to prevent Memory Write Block (MWB) from
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		 * occurring when accessing our register space */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	/* Set the PCI priority bit correctly in the CTRL register.  This
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	 * determines if the adapter gives priority to receives, or if it
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	 * gives equal priority to transmits and receives.  Valid only on
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	 * 82542 and 82543 silicon.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		ew32(CTRL, ctrl | E1000_CTRL_PRIOR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	case e1000_82545_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	case e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
		/* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
		if (hw->bus_type == e1000_bus_type_pcix
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
		    && e1000_pcix_get_mmrbc(hw) > 2048)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
			e1000_pcix_set_mmrbc(hw, 2048);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	/* Call a subroutine to configure the link and setup flow control. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	ret_val = e1000_setup_link(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	/* Set the transmit descriptor write-back policy */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	if (hw->mac_type > e1000_82544) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		ctrl = er32(TXDCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		ctrl =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		    (ctrl & ~E1000_TXDCTL_WTHRESH) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		    E1000_TXDCTL_FULL_TX_DESC_WB;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		ew32(TXDCTL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	/* Clear all of the statistics registers (clear on read).  It is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	 * important that we do this after we have tried to establish link
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	 * because the symbol error count will increment wildly if there
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	 * is no link.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	e1000_clear_hw_cntrs(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	    hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		ctrl_ext = er32(CTRL_EXT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		/* Relaxed ordering must be disabled to avoid a parity
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		 * error crash in a PCI slot. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		ew32(CTRL_EXT, ctrl_ext);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
 * e1000_adjust_serdes_amplitude - Adjust SERDES output amplitude based on EEPROM setting.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
 * @hw: Struct containing variables accessed by shared code.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	u16 eeprom_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	e_dbg("e1000_adjust_serdes_amplitude");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	if (hw->media_type != e1000_media_type_internal_serdes)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
	case e1000_82545_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	case e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	                            &eeprom_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	if (eeprom_data != EEPROM_RESERVED_WORD) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
		/* Adjust SERDES output amplitude only. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
		eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
		    e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
 * e1000_setup_link - Configures flow control and link settings.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
 * Determines which flow control settings to use. Calls the appropriate media-
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
 * specific link configuration function. Configures the flow control settings.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
 * Assuming the adapter has a valid link partner, a valid link should be
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
 * established. Assumes the hardware has previously been reset and the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
 * transmitter and receiver are not enabled.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
s32 e1000_setup_link(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	u32 ctrl_ext;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	u16 eeprom_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	e_dbg("e1000_setup_link");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	/* Read and store word 0x0F of the EEPROM. This word contains bits
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	 * that determine the hardware's default PAUSE (flow control) mode,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	 * a bit that determines whether the HW defaults to enabling or
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	 * disabling auto-negotiation, and the direction of the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	 * SW defined pins. If there is no SW over-ride of the flow
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	 * control setting, then the variable hw->fc will
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	 * be initialized based on a value in the EEPROM.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	if (hw->fc == E1000_FC_DEFAULT) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
		ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
					    1, &eeprom_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
			e_dbg("EEPROM Read Error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
			return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
		if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
			hw->fc = E1000_FC_NONE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
		else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
			 EEPROM_WORD0F_ASM_DIR)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
			hw->fc = E1000_FC_TX_PAUSE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
			hw->fc = E1000_FC_FULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	/* We want to save off the original Flow Control configuration just
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
	 * in case we get disconnected and then reconnected into a different
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	 * hub or switch with different Flow Control capabilities.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	if (hw->mac_type == e1000_82542_rev2_0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
		hw->fc &= (~E1000_FC_TX_PAUSE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		hw->fc &= (~E1000_FC_RX_PAUSE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	hw->original_fc = hw->fc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	/* Take the 4 bits from EEPROM word 0x0F that determine the initial
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	 * polarity value for the SW controlled pins, and setup the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	 * Extended Device Control reg with that info.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	 * This is needed because one of the SW controlled pins is used for
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	 * signal detection.  So this should be done before e1000_setup_pcs_link()
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	 * or e1000_phy_setup() is called.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	if (hw->mac_type == e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
		ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
					    1, &eeprom_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
			e_dbg("EEPROM Read Error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
			return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
			    SWDPIO__EXT_SHIFT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		ew32(CTRL_EXT, ctrl_ext);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	/* Call the necessary subroutine to configure the link. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	ret_val = (hw->media_type == e1000_media_type_copper) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	    e1000_setup_copper_link(hw) : e1000_setup_fiber_serdes_link(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	/* Initialize the flow control address, type, and PAUSE timer
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	 * registers to their default values.  This is done even if flow
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	 * control is disabled, because it does not hurt anything to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	 * initialize these registers.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	e_dbg("Initializing the Flow Control address, type and timer regs\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	ew32(FCT, FLOW_CONTROL_TYPE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	ew32(FCTTV, hw->fc_pause_time);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	/* Set the flow control receive threshold registers.  Normally,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	 * these registers will be set to a default threshold that may be
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	 * adjusted later by the driver's runtime code.  However, if the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	 * ability to transmit pause frames in not enabled, then these
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	 * registers will be set to 0.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	if (!(hw->fc & E1000_FC_TX_PAUSE)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
		ew32(FCRTL, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		ew32(FCRTH, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
		/* We need to set up the Receive Threshold high and low water marks
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
		 * as well as (optionally) enabling the transmission of XON frames.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
		if (hw->fc_send_xon) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
			ew32(FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
			ew32(FCRTH, hw->fc_high_water);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
			ew32(FCRTL, hw->fc_low_water);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
			ew32(FCRTH, hw->fc_high_water);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
 * e1000_setup_fiber_serdes_link - prepare fiber or serdes link
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
 * Manipulates Physical Coding Sublayer functions in order to configure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
 * link. Assumes the hardware has been previously reset and the transmitter
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
 * and receiver are not enabled.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	u32 status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	u32 txcw = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	u32 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	u32 signal = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	e_dbg("e1000_setup_fiber_serdes_link");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	/* On adapters with a MAC newer than 82544, SWDP 1 will be
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	 * set when the optics detect a signal. On older adapters, it will be
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	 * cleared when there is a signal.  This applies to fiber media only.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	 * If we're on serdes media, adjust the output amplitude to value
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	 * set in the EEPROM.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	if (hw->media_type == e1000_media_type_fiber)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
		signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	ret_val = e1000_adjust_serdes_amplitude(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	/* Take the link out of reset */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	ctrl &= ~(E1000_CTRL_LRST);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	/* Adjust VCO speed to improve BER performance */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	ret_val = e1000_set_vco_speed(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
	e1000_config_collision_dist(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	/* Check for a software override of the flow control settings, and setup
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	 * the device accordingly.  If auto-negotiation is enabled, then software
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	 * will have to set the "PAUSE" bits to the correct value in the Tranmsit
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	 * Config Word Register (TXCW) and re-start auto-negotiation.  However, if
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	 * auto-negotiation is disabled, then software will have to manually
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	 * configure the two flow control enable bits in the CTRL register.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	 * The possible values of the "fc" parameter are:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	 *      0:  Flow control is completely disabled
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	 *      1:  Rx flow control is enabled (we can receive pause frames, but
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	 *          not send pause frames).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	 *      2:  Tx flow control is enabled (we can send pause frames but we do
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	 *          not support receiving pause frames).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	switch (hw->fc) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	case E1000_FC_NONE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
		/* Flow control is completely disabled by a software over-ride. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	case E1000_FC_RX_PAUSE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
		/* RX Flow control is enabled and TX Flow control is disabled by a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		 * software over-ride. Since there really isn't a way to advertise
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		 * that we are capable of RX Pause ONLY, we will advertise that we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
		 * support both symmetric and asymmetric RX PAUSE. Later, we will
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
		 *  disable the adapter's ability to send PAUSE frames.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	case E1000_FC_TX_PAUSE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		/* TX Flow control is enabled, and RX Flow control is disabled, by a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		 * software over-ride.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	case E1000_FC_FULL:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
		/* Flow control (both RX and TX) is enabled by a software over-ride. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
		e_dbg("Flow control param set incorrectly\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
		return -E1000_ERR_CONFIG;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	/* Since auto-negotiation is enabled, take the link out of reset (the link
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
	 * will be in reset, because we previously reset the chip). This will
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	 * restart auto-negotiation.  If auto-negotiation is successful then the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	 * link-up status bit will be set and the flow control enable bits (RFCE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	 * and TFCE) will be set according to their negotiated value.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	e_dbg("Auto-negotiation enabled\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	ew32(TXCW, txcw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	hw->txcw = txcw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	msleep(1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	/* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	 * indication in the Device Status Register.  Time-out if a link isn't
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	 * seen in 500 milliseconds seconds (Auto-negotiation should complete in
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	 * less than 500 milliseconds even if the other end is doing it in SW).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	 * For internal serdes, we just assume a signal is present, then poll.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	if (hw->media_type == e1000_media_type_internal_serdes ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	    (er32(CTRL) & E1000_CTRL_SWDPIN1) == signal) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
		e_dbg("Looking for Link\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
		for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
			msleep(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
			status = er32(STATUS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
			if (status & E1000_STATUS_LU)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
		if (i == (LINK_UP_TIMEOUT / 10)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
			e_dbg("Never got a valid link from auto-neg!!!\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
			hw->autoneg_failed = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
			/* AutoNeg failed to achieve a link, so we'll call
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
			 * e1000_check_for_link. This routine will force the link up if
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
			 * we detect a signal. This will allow us to communicate with
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
			 * non-autonegotiating link partners.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
			ret_val = e1000_check_for_link(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
			if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
				e_dbg("Error while checking for link\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
			hw->autoneg_failed = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
			hw->autoneg_failed = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
			e_dbg("Valid Link Found\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
		e_dbg("No Signal Detected\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
 * e1000_copper_link_preconfig - early configuration for copper
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
 * Make sure we have a valid PHY and change PHY mode before link setup.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
static s32 e1000_copper_link_preconfig(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	e_dbg("e1000_copper_link_preconfig");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	/* With 82543, we need to force speed and duplex on the MAC equal to what
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	 * the PHY speed and duplex configuration is. In addition, we need to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	 * perform a hardware reset on the PHY to take it out of reset.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	if (hw->mac_type > e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
		ctrl |= E1000_CTRL_SLU;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
		ctrl |=
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		    (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
		ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
		ret_val = e1000_phy_hw_reset(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	/* Make sure we have a valid PHY */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	ret_val = e1000_detect_gig_phy(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
		e_dbg("Error, did not detect valid phy.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	e_dbg("Phy ID = %x\n", hw->phy_id);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	/* Set PHY to class A mode (if necessary) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	ret_val = e1000_set_phy_mode(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	if ((hw->mac_type == e1000_82545_rev_3) ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	    (hw->mac_type == e1000_82546_rev_3)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
		phy_data |= 0x00000008;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	if (hw->mac_type <= e1000_82543 ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	    hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	    hw->mac_type == e1000_82541_rev_2
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	    || hw->mac_type == e1000_82547_rev_2)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
		hw->phy_reset_disable = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
 * e1000_copper_link_igp_setup - Copper link setup for e1000_phy_igp series.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
static s32 e1000_copper_link_igp_setup(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	u32 led_ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
	e_dbg("e1000_copper_link_igp_setup");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	if (hw->phy_reset_disable)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	ret_val = e1000_phy_reset(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		e_dbg("Error Resetting the PHY\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	/* Wait 15ms for MAC to configure PHY from eeprom settings */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	msleep(15);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	/* Configure activity LED after PHY reset */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	led_ctrl = er32(LEDCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	led_ctrl &= IGP_ACTIVITY_LED_MASK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	ew32(LEDCTL, led_ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	/* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	if (hw->phy_type == e1000_phy_igp) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
		/* disable lplu d3 during driver init */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		ret_val = e1000_set_d3_lplu_state(hw, false);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
			e_dbg("Error Disabling LPLU D3\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	/* Configure mdi-mdix settings */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
		hw->dsp_config_state = e1000_dsp_config_disabled;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		/* Force MDI for earlier revs of the IGP PHY */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		phy_data &=
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
		    ~(IGP01E1000_PSCR_AUTO_MDIX |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
		      IGP01E1000_PSCR_FORCE_MDI_MDIX);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		hw->mdix = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		hw->dsp_config_state = e1000_dsp_config_enabled;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		switch (hw->mdix) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
		case 1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
			phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
		case 2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
			phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
		case 0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
		default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
			phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	/* set auto-master slave resolution settings */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	if (hw->autoneg) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		e1000_ms_type phy_ms_setting = hw->master_slave;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
		if (hw->ffe_config_state == e1000_ffe_config_active)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
			hw->ffe_config_state = e1000_ffe_config_enabled;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		if (hw->dsp_config_state == e1000_dsp_config_activated)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
			hw->dsp_config_state = e1000_dsp_config_enabled;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		/* when autonegotiation advertisement is only 1000Mbps then we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		 * should disable SmartSpeed and enable Auto MasterSlave
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		 * resolution as hardware default. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		if (hw->autoneg_advertised == ADVERTISE_1000_FULL) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
			/* Disable SmartSpeed */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
					       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
						phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
			/* Set auto Master/Slave resolution process */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
			    e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
			phy_data &= ~CR_1000T_MS_ENABLE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
			    e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
		/* load defaults for future use */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		    ((phy_data & CR_1000T_MS_VALUE) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		     e1000_ms_force_master :
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		     e1000_ms_force_slave) : e1000_ms_auto;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
		switch (phy_ms_setting) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		case e1000_ms_force_master:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
			phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
		case e1000_ms_force_slave:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
			phy_data |= CR_1000T_MS_ENABLE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
			phy_data &= ~(CR_1000T_MS_VALUE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		case e1000_ms_auto:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
			phy_data &= ~CR_1000T_MS_ENABLE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
 * e1000_copper_link_mgp_setup - Copper link setup for e1000_phy_m88 series.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
static s32 e1000_copper_link_mgp_setup(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	e_dbg("e1000_copper_link_mgp_setup");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	if (hw->phy_reset_disable)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
	/* Enable CRS on TX. This must be set for half-duplex operation. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	/* Options:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	 *   MDI/MDI-X = 0 (default)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	 *   0 - Auto for all speeds
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	 *   1 - MDI mode
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	 *   2 - MDI-X mode
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	switch (hw->mdix) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	case 1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
	case 2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
	case 3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
	case 0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
	/* Options:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	 *   disable_polarity_correction = 0 (default)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	 *       Automatic Correction for Reversed Cable Polarity
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	 *   0 - Disabled
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	 *   1 - Enabled
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
	if (hw->disable_polarity_correction == 1)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
	if (hw->phy_revision < M88E1011_I_REV_4) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
		/* Force TX_CLK in the Extended PHY Specific Control Register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		 * to 25MHz clock.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		    e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
				       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
		if ((hw->phy_revision == E1000_REVISION_2) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		    (hw->phy_id == M88E1111_I_PHY_ID)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
			/* Vidalia Phy, set the downshift counter to 5x */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
			phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
			ret_val = e1000_write_phy_reg(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
						      M88E1000_EXT_PHY_SPEC_CTRL,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
						      phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
			/* Configure Master and Slave downshift values */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
				      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
			ret_val = e1000_write_phy_reg(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
						      M88E1000_EXT_PHY_SPEC_CTRL,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
						      phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	/* SW Reset the PHY so all changes take effect */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	ret_val = e1000_phy_reset(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
		e_dbg("Error Resetting the PHY\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
 * e1000_copper_link_autoneg - setup auto-neg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 * Setup auto-negotiation and flow control advertisements,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
 * and then perform auto-negotiation.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	e_dbg("e1000_copper_link_autoneg");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	/* Perform some bounds checking on the hw->autoneg_advertised
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	 * parameter.  If this variable is zero, then set it to the default.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	/* If autoneg_advertised is zero, we assume it was not defaulted
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	 * by the calling code so we set to advertise full capability.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	if (hw->autoneg_advertised == 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
		hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	e_dbg("Reconfiguring auto-neg advertisement params\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	ret_val = e1000_phy_setup_autoneg(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
	if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		e_dbg("Error Setting up Auto-Negotiation\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	e_dbg("Restarting Auto-Neg\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	 * the Auto Neg Restart bit in the PHY control register.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
	/* Does the user want to wait for Auto-Neg to complete here, or
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	 * check at a later time (for example, callback routine).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	if (hw->wait_autoneg_complete) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
		ret_val = e1000_wait_autoneg(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
			e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
			    ("Error while waiting for autoneg to complete\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
	hw->get_link_status = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
 * e1000_copper_link_postconfig - post link setup
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
 * Config the MAC and the PHY after link is up.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
 *   1) Set up the MAC to the current PHY speed/duplex
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
 *      if we are on 82543.  If we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
 *      are on newer silicon, we only need to configure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
 *      collision distance in the Transmit Control Register.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
 *   2) Set up flow control on the MAC to that established with
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
 *      the link partner.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
 *   3) Config DSP to improve Gigabit link quality for some PHY revisions.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
static s32 e1000_copper_link_postconfig(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	e_dbg("e1000_copper_link_postconfig");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	if (hw->mac_type >= e1000_82544) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
		e1000_config_collision_dist(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
		ret_val = e1000_config_mac_to_phy(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
			e_dbg("Error configuring MAC to PHY settings\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	ret_val = e1000_config_fc_after_link_up(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
		e_dbg("Error Configuring Flow Control\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
	/* Config DSP to improve Giga link quality */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	if (hw->phy_type == e1000_phy_igp) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
		ret_val = e1000_config_dsp_after_link_change(hw, true);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
			e_dbg("Error Configuring DSP after link up\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
 * e1000_setup_copper_link - phy/speed/duplex setting
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
 * Detects which PHY is present and sets up the speed and duplex
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
static s32 e1000_setup_copper_link(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	u16 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	e_dbg("e1000_setup_copper_link");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	/* Check if it is a valid PHY and set PHY mode if necessary. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	ret_val = e1000_copper_link_preconfig(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	if (hw->phy_type == e1000_phy_igp) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
		ret_val = e1000_copper_link_igp_setup(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	} else if (hw->phy_type == e1000_phy_m88) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
		ret_val = e1000_copper_link_mgp_setup(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
	if (hw->autoneg) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
		/* Setup autoneg and flow control advertisement
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
		 * and perform autonegotiation */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		ret_val = e1000_copper_link_autoneg(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		/* PHY will be set to 10H, 10F, 100H,or 100F
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
		 * depending on value from forced_speed_duplex. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		e_dbg("Forcing speed and duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		ret_val = e1000_phy_force_speed_duplex(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
			e_dbg("Error Forcing Speed and Duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	/* Check link status. Wait up to 100 microseconds for link to become
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	 * valid.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	for (i = 0; i < 10; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
		if (phy_data & MII_SR_LINK_STATUS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
			/* Config the MAC and PHY after link is up */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
			ret_val = e1000_copper_link_postconfig(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
			e_dbg("Valid link established!!!\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
			return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
		udelay(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	e_dbg("Unable to establish link!!!\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
 * e1000_phy_setup_autoneg - phy settings
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
 * Configures PHY autoneg and flow control advertisement settings
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	u16 mii_autoneg_adv_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	u16 mii_1000t_ctrl_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
	e_dbg("e1000_phy_setup_autoneg");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
	/* Read the MII 1000Base-T Control Register (Address 9). */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	    e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	/* Need to parse both autoneg_advertised and fc and set up
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	 * the appropriate PHY registers.  First we will parse for
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	 * autoneg_advertised software override.  Since we can advertise
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
	 * a plethora of combinations, we need to check each bit
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	 * individually.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
	 * the  1000Base-T Control Register (Address 9).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	e_dbg("autoneg_advertised %x\n", hw->autoneg_advertised);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	/* Do we want to advertise 10 Mb Half Duplex? */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
		e_dbg("Advertise 10mb Half duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	/* Do we want to advertise 10 Mb Full Duplex? */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		e_dbg("Advertise 10mb Full duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
	/* Do we want to advertise 100 Mb Half Duplex? */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
	if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
		e_dbg("Advertise 100mb Half duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	/* Do we want to advertise 100 Mb Full Duplex? */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
		e_dbg("Advertise 100mb Full duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
		e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		    ("Advertise 1000mb Half duplex requested, request denied!\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	/* Do we want to advertise 1000 Mb Full Duplex? */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
		e_dbg("Advertise 1000mb Full duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
	/* Check for a software override of the flow control settings, and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	 * setup the PHY advertisement registers accordingly.  If
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	 * auto-negotiation is enabled, then software will have to set the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	 * "PAUSE" bits to the correct value in the Auto-Negotiation
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	 * The possible values of the "fc" parameter are:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
	 *      0:  Flow control is completely disabled
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	 *      1:  Rx flow control is enabled (we can receive pause frames
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	 *          but not send pause frames).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
	 *      2:  Tx flow control is enabled (we can send pause frames
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	 *          but we do not support receiving pause frames).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	 *  other:  No software override.  The flow control configuration
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	 *          in the EEPROM is used.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	switch (hw->fc) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	case E1000_FC_NONE:	/* 0 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
		/* Flow control (RX & TX) is completely disabled by a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		 * software over-ride.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	case E1000_FC_RX_PAUSE:	/* 1 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		/* RX Flow control is enabled, and TX Flow control is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		 * disabled, by a software over-ride.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
		/* Since there really isn't a way to advertise that we are
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		 * capable of RX Pause ONLY, we will advertise that we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		 * support both symmetric and asymmetric RX PAUSE.  Later
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		 * (in e1000_config_fc_after_link_up) we will disable the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		 *hw's ability to send PAUSE frames.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	case E1000_FC_TX_PAUSE:	/* 2 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
		/* TX Flow control is enabled, and RX Flow control is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
		 * disabled, by a software over-ride.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
	case E1000_FC_FULL:	/* 3 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
		/* Flow control (both RX and TX) is enabled by a software
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
		 * over-ride.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
		e_dbg("Flow control param set incorrectly\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
		return -E1000_ERR_CONFIG;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
 * e1000_phy_force_speed_duplex - force link settings
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
 * Force PHY speed and duplex settings to hw->forced_speed_duplex
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	u16 mii_ctrl_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	u16 mii_status_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	u16 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	e_dbg("e1000_phy_force_speed_duplex");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	/* Turn off Flow control if we are forcing speed and duplex. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	hw->fc = E1000_FC_NONE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	e_dbg("hw->fc = %d\n", hw->fc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	/* Read the Device Control Register. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	/* Set the bits to Force Speed and Duplex in the Device Ctrl Reg. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	ctrl &= ~(DEVICE_SPEED_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	/* Clear the Auto Speed Detect Enable bit. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	ctrl &= ~E1000_CTRL_ASDE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
	/* Read the MII Control Register. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
	/* We need to disable autoneg in order to force link and duplex. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
	mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
	/* Are we forcing Full or Half Duplex? */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	if (hw->forced_speed_duplex == e1000_100_full ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	    hw->forced_speed_duplex == e1000_10_full) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
		/* We want to force full duplex so we SET the full duplex bits in the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		 * Device and MII Control Registers.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		ctrl |= E1000_CTRL_FD;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		mii_ctrl_reg |= MII_CR_FULL_DUPLEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		e_dbg("Full Duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
		/* We want to force half duplex so we CLEAR the full duplex bits in
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		 * the Device and MII Control Registers.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
		ctrl &= ~E1000_CTRL_FD;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		mii_ctrl_reg &= ~MII_CR_FULL_DUPLEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		e_dbg("Half Duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
	/* Are we forcing 100Mbps??? */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
	if (hw->forced_speed_duplex == e1000_100_full ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
	    hw->forced_speed_duplex == e1000_100_half) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
		/* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		ctrl |= E1000_CTRL_SPD_100;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		mii_ctrl_reg |= MII_CR_SPEED_100;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		e_dbg("Forcing 100mb ");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
		/* Set the 10Mb bit and turn off the 1000Mb and 100Mb bits. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
		mii_ctrl_reg |= MII_CR_SPEED_10;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
		mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
		e_dbg("Forcing 10mb ");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
	e1000_config_collision_dist(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
	/* Write the configured values back to the Device Control Reg. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	if (hw->phy_type == e1000_phy_m88) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		/* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
		 * forced whenever speed are duplex are forced.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
		phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
		e_dbg("M88E1000 PSCR: %x\n", phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
		/* Need to reset the PHY or these changes will be ignored */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
		mii_ctrl_reg |= MII_CR_RESET;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
		/* Disable MDI-X support for 10/100 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
		/* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
		 * forced whenever speed or duplex are forced.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	/* Write back the modified PHY MII control register. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	udelay(1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	/* The wait_autoneg_complete flag may be a little misleading here.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
	 * Since we are forcing speed and duplex, Auto-Neg is not enabled.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	 * But we do want to delay for a period while forcing only so we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	 * don't generate false No Link messages.  So we will wait here
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	 * only if the user has set wait_autoneg_complete to 1, which is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	 * the default.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	if (hw->wait_autoneg_complete) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
		/* We will wait for autoneg to complete. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
		e_dbg("Waiting for forced speed/duplex link.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
		mii_status_reg = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		/* We will wait for autoneg to complete or 4.5 seconds to expire. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		for (i = PHY_FORCE_TIME; i > 0; i--) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
			/* Read the MII Status Register and wait for Auto-Neg Complete bit
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
			 * to be set.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
			if (mii_status_reg & MII_SR_LINK_STATUS)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
			msleep(100);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		if ((i == 0) && (hw->phy_type == e1000_phy_m88)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
			/* We didn't get link.  Reset the DSP and wait again for link. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
			ret_val = e1000_phy_reset_dsp(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
			if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
				e_dbg("Error Resetting PHY DSP\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		/* This loop will early-out if the link condition has been met.  */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
		for (i = PHY_FORCE_TIME; i > 0; i--) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
			if (mii_status_reg & MII_SR_LINK_STATUS)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
			msleep(100);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
			/* Read the MII Status Register and wait for Auto-Neg Complete bit
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
			 * to be set.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	if (hw->phy_type == e1000_phy_m88) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		/* Because we reset the PHY above, we need to re-force TX_CLK in the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		 * Extended PHY Specific Control Register to 25MHz clock.  This value
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		 * defaults back to a 2.5MHz clock when the PHY is reset.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		    e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
				       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		    e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
					phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
		/* In addition, because of the s/w reset above, we need to enable CRS on
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
		 * TX.  This must be set for both full and half duplex operation.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
		phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
		if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
		    && (!hw->autoneg)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		    && (hw->forced_speed_duplex == e1000_10_full
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
			|| hw->forced_speed_duplex == e1000_10_half)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
			ret_val = e1000_polarity_reversal_workaround(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
 * e1000_config_collision_dist - set collision distance register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
 * Sets the collision distance in the Transmit Control register.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
 * Link should have been established previously. Reads the speed and duplex
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
 * information from the Device Status register.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
void e1000_config_collision_dist(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
	u32 tctl, coll_dist;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	e_dbg("e1000_config_collision_dist");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
	if (hw->mac_type < e1000_82543)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
		coll_dist = E1000_COLLISION_DISTANCE_82542;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		coll_dist = E1000_COLLISION_DISTANCE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
	tctl = er32(TCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	tctl &= ~E1000_TCTL_COLD;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	tctl |= coll_dist << E1000_COLD_SHIFT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
	ew32(TCTL, tctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
 * e1000_config_mac_to_phy - sync phy and mac settings
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
 * @mii_reg: data to write to the MII control register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
 * Sets MAC speed and duplex settings to reflect the those in the PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
 * The contents of the PHY register containing the needed information need to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
 * be passed in.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
	e_dbg("e1000_config_mac_to_phy");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	/* 82544 or newer MAC, Auto Speed Detection takes care of
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	 * MAC speed/duplex configuration.*/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	if (hw->mac_type >= e1000_82544)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
	/* Read the Device Control Register and set the bits to Force Speed
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	 * and Duplex.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	/* Set up duplex in the Device Control and Transmit Control
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	 * registers depending on negotiated values.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	if (phy_data & M88E1000_PSSR_DPLX)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
		ctrl |= E1000_CTRL_FD;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		ctrl &= ~E1000_CTRL_FD;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	e1000_config_collision_dist(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
	/* Set up speed in the Device Control register depending on
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
	 * negotiated values.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
		ctrl |= E1000_CTRL_SPD_1000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
	else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
		ctrl |= E1000_CTRL_SPD_100;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	/* Write the configured values back to the Device Control Reg. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
 * e1000_force_mac_fc - force flow control settings
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
 * Forces the MAC's flow control settings.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
 * Sets the TFCE and RFCE bits in the device control register to reflect
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
 * the adapter settings. TFCE and RFCE need to be explicitly set by
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
 * software when a Copper PHY is used because autonegotiation is managed
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
 * by the PHY rather than the MAC. Software must also configure these
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
 * bits when link is forced on a fiber connection.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
s32 e1000_force_mac_fc(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
	u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
	e_dbg("e1000_force_mac_fc");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
	/* Get the current configuration of the Device Control Register */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
	/* Because we didn't get link via the internal auto-negotiation
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	 * mechanism (we either forced link or we got link via PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	 * auto-neg), we have to manually enable/disable transmit an
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	 * receive flow control.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
	 * The "Case" statement below enables/disable flow control
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
	 * according to the "hw->fc" parameter.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	 * The possible values of the "fc" parameter are:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
	 *      0:  Flow control is completely disabled
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	 *      1:  Rx flow control is enabled (we can receive pause
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	 *          frames but not send pause frames).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	 *      2:  Tx flow control is enabled (we can send pause frames
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	 *          frames but we do not receive pause frames).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	 *      3:  Both Rx and TX flow control (symmetric) is enabled.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
	 *  other:  No other values should be possible at this point.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
	switch (hw->fc) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	case E1000_FC_NONE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
	case E1000_FC_RX_PAUSE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
		ctrl &= (~E1000_CTRL_TFCE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
		ctrl |= E1000_CTRL_RFCE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	case E1000_FC_TX_PAUSE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
		ctrl &= (~E1000_CTRL_RFCE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
		ctrl |= E1000_CTRL_TFCE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	case E1000_FC_FULL:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
		e_dbg("Flow control param set incorrectly\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
		return -E1000_ERR_CONFIG;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
	/* Disable TX Flow Control for 82542 (rev 2.0) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	if (hw->mac_type == e1000_82542_rev2_0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
		ctrl &= (~E1000_CTRL_TFCE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
	ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
 * e1000_config_fc_after_link_up - configure flow control after autoneg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
 * Configures flow control settings after link is established
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
 * Should be called immediately after a valid link has been established.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
 * Forces MAC flow control settings if link was forced. When in MII/GMII mode
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
 * and autonegotiation is enabled, the MAC flow control settings will be set
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
 * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
 * and RFCE bits will be automatically set to the negotiated flow control mode.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	u16 mii_status_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	u16 mii_nway_adv_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	u16 mii_nway_lp_ability_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
	u16 speed;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
	u16 duplex;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
	e_dbg("e1000_config_fc_after_link_up");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
	/* Check for the case where we have fiber media and auto-neg failed
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
	 * so we had to force link.  In this case, we need to force the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	 * configuration of the MAC to match the "fc" parameter.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	    || ((hw->media_type == e1000_media_type_internal_serdes)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
		&& (hw->autoneg_failed))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	    || ((hw->media_type == e1000_media_type_copper)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
		&& (!hw->autoneg))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
		ret_val = e1000_force_mac_fc(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
			e_dbg("Error forcing flow control settings\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	/* Check for the case where we have copper media and auto-neg is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	 * enabled.  In this case, we need to check and see if Auto-Neg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	 * has completed, and if so, how the PHY and link partner has
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	 * flow control configured.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	if ((hw->media_type == e1000_media_type_copper) && hw->autoneg) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
		/* Read the MII Status Register and check to see if AutoNeg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
		 * has completed.  We read this twice because this reg has
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
		 * some "sticky" (latched) bits.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
		if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
			/* The AutoNeg process has completed, so we now need to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
			 * read both the Auto Negotiation Advertisement Register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
			 * (Address 4) and the Auto_Negotiation Base Page Ability
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
			 * Register (Address 5) to determine how flow control was
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
			 * negotiated.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
			ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
						     &mii_nway_adv_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
			ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
						     &mii_nway_lp_ability_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
			/* Two bits in the Auto Negotiation Advertisement Register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
			 * (Address 4) and two bits in the Auto Negotiation Base
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
			 * Page Ability Register (Address 5) determine flow control
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
			 * for both the PHY and the link partner.  The following
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
			 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
			 * 1999, describes these PAUSE resolution bits and how flow
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
			 * control is determined based upon these settings.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
			 * NOTE:  DC = Don't Care
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
			 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
			 *   LOCAL DEVICE  |   LINK PARTNER
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
			 *-------|---------|-------|---------|--------------------
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
			 *   0   |    0    |  DC   |   DC    | E1000_FC_NONE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
			 *   0   |    1    |   0   |   DC    | E1000_FC_NONE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
			 *   0   |    1    |   1   |    0    | E1000_FC_NONE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
			 *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
			 *   1   |    0    |   0   |   DC    | E1000_FC_NONE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
			 *   1   |    1    |   0   |    0    | E1000_FC_NONE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
			 *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
			 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
			/* Are both PAUSE bits set to 1?  If so, this implies
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			 * Symmetric Flow Control is enabled at both ends.  The
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
			 * ASM_DIR bits are irrelevant per the spec.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
			 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
			 * For Symmetric Flow Control:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
			 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
			 *   LOCAL DEVICE  |   LINK PARTNER
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
			 *-------|---------|-------|---------|--------------------
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
			 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
			if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
			    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
				/* Now we need to check if the user selected RX ONLY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
				 * of pause frames.  In this case, we had to advertise
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
				 * FULL flow control because we could not advertise RX
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
				 * ONLY. Hence, we must now check to see if we need to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
				 * turn OFF  the TRANSMISSION of PAUSE frames.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
				 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
				if (hw->original_fc == E1000_FC_FULL) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
					hw->fc = E1000_FC_FULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
					e_dbg("Flow Control = FULL.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
				} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
					hw->fc = E1000_FC_RX_PAUSE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
					e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
					    ("Flow Control = RX PAUSE frames only.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
				}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
			/* For receiving PAUSE frames ONLY.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
			 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
			 *   LOCAL DEVICE  |   LINK PARTNER
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
			 *-------|---------|-------|---------|--------------------
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
			 *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
			 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
			else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
				 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
			{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
				hw->fc = E1000_FC_TX_PAUSE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
				e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
				    ("Flow Control = TX PAUSE frames only.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
			/* For transmitting PAUSE frames ONLY.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
			 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
			 *   LOCAL DEVICE  |   LINK PARTNER
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
			 *-------|---------|-------|---------|--------------------
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
			 *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
			 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
			else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
				 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
			{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
				hw->fc = E1000_FC_RX_PAUSE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
				e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
				    ("Flow Control = RX PAUSE frames only.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
			/* Per the IEEE spec, at this point flow control should be
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
			 * disabled.  However, we want to consider that we could
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
			 * be connected to a legacy switch that doesn't advertise
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
			 * desired flow control, but can be forced on the link
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
			 * partner.  So if we advertised no flow control, that is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
			 * what we will resolve to.  If we advertised some kind of
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
			 * receive capability (Rx Pause Only or Full Flow Control)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
			 * and the link partner advertised none, we will configure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
			 * ourselves to enable Rx Flow Control only.  We can do
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
			 * this safely for two reasons:  If the link partner really
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
			 * didn't want flow control enabled, and we enable Rx, no
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
			 * harm done since we won't be receiving any PAUSE frames
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
			 * anyway.  If the intent on the link partner was to have
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
			 * flow control enabled, then by us enabling RX only, we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
			 * can at least receive pause frames and process them.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
			 * This is a good idea because in most cases, since we are
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
			 * predominantly a server NIC, more times than not we will
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
			 * be asked to delay transmission of packets than asking
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
			 * our link partner to pause transmission of frames.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
			else if ((hw->original_fc == E1000_FC_NONE ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
				  hw->original_fc == E1000_FC_TX_PAUSE) ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
				 hw->fc_strict_ieee) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
				hw->fc = E1000_FC_NONE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
				e_dbg("Flow Control = NONE.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
			} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
				hw->fc = E1000_FC_RX_PAUSE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
				e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
				    ("Flow Control = RX PAUSE frames only.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
			/* Now we need to do one last check...  If we auto-
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
			 * negotiated to HALF DUPLEX, flow control should not be
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
			 * enabled per IEEE 802.3 spec.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
			if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
				e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
				    ("Error getting link speed and duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
			if (duplex == HALF_DUPLEX)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
				hw->fc = E1000_FC_NONE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
			/* Now we call a subroutine to actually force the MAC
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
			 * controller to use the correct flow control settings.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
			ret_val = e1000_force_mac_fc(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
			if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
				e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
				    ("Error forcing flow control settings\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
			e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
			    ("Copper PHY and Auto Neg has not completed.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
 * e1000_check_for_serdes_link_generic - Check for link (Serdes)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
 * @hw: pointer to the HW structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
 * Checks for link up on the hardware.  If link is not up and we have
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
 * a signal, then we need to force link up.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
static s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	u32 rxcw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
	u32 status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	s32 ret_val = E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
	e_dbg("e1000_check_for_serdes_link_generic");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	status = er32(STATUS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
	rxcw = er32(RXCW);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
	/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	 * If we don't have link (auto-negotiation failed or link partner
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
	 * cannot auto-negotiate), and our link partner is not trying to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	 * auto-negotiate with us (we are receiving idles or data),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	 * we need to force link up. We also need to give auto-negotiation
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	 * time to complete.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
		if (hw->autoneg_failed == 0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
			hw->autoneg_failed = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
			goto out;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
		e_dbg("NOT RXing /C/, disable AutoNeg and force link.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
		/* Disable auto-negotiation in the TXCW register */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
		ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
		/* Force link-up and also force full-duplex. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
		ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
		ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
		/* Configure Flow Control after forcing link up. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
		ret_val = e1000_config_fc_after_link_up(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
			e_dbg("Error configuring flow control\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
			goto out;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
		/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
		 * If we are forcing link and we are receiving /C/ ordered
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
		 * sets, re-enable auto-negotiation in the TXCW register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
		 * and disable forced link in the Device Control register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
		 * in an attempt to auto-negotiate with our link partner.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
		e_dbg("RXing /C/, enable AutoNeg and stop forcing link.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
		ew32(TXCW, hw->txcw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
		hw->serdes_has_link = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
		/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
		 * If we force link for non-auto-negotiation switch, check
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
		 * link status based on MAC synchronization for internal
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
		 * serdes media type.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
		/* SYNCH bit and IV bit are sticky. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
		udelay(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
		rxcw = er32(RXCW);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
		if (rxcw & E1000_RXCW_SYNCH) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
			if (!(rxcw & E1000_RXCW_IV)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
				hw->serdes_has_link = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
				e_dbg("SERDES: Link up - forced.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
			hw->serdes_has_link = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
			e_dbg("SERDES: Link down - force failed.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	if (E1000_TXCW_ANE & er32(TXCW)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
		status = er32(STATUS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
		if (status & E1000_STATUS_LU) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
			/* SYNCH bit and IV bit are sticky, so reread rxcw. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
			udelay(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
			rxcw = er32(RXCW);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
			if (rxcw & E1000_RXCW_SYNCH) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
				if (!(rxcw & E1000_RXCW_IV)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
					hw->serdes_has_link = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
					e_dbg("SERDES: Link up - autoneg "
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
						 "completed successfully.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
				} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
					hw->serdes_has_link = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
					e_dbg("SERDES: Link down - invalid"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
						 "codewords detected in autoneg.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
				}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
			} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
				hw->serdes_has_link = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
				e_dbg("SERDES: Link down - no sync.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
			hw->serdes_has_link = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
			e_dbg("SERDES: Link down - autoneg failed\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
      out:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
 * e1000_check_for_link
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
 * Checks to see if the link status of the hardware has changed.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
 * Called by any function that needs to check the link status of the adapter.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
s32 e1000_check_for_link(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	u32 rxcw __attribute__ ((unused)) = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	u32 ctrl __attribute__ ((unused));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	u32 status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	u32 rctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	u32 icr;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	u32 signal __attribute__ ((unused)) = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
	e_dbg("e1000_check_for_link");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
	ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
	status = er32(STATUS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	/* On adapters with a MAC newer than 82544, SW Definable pin 1 will be
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
	 * set when the optics detect a signal. On older adapters, it will be
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	 * cleared when there is a signal.  This applies to fiber media only.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	if ((hw->media_type == e1000_media_type_fiber) ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	    (hw->media_type == e1000_media_type_internal_serdes)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
		rxcw = er32(RXCW);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
		if (hw->media_type == e1000_media_type_fiber) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
			signal =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
			    (hw->mac_type >
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
			     e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
			if (status & E1000_STATUS_LU)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
				hw->get_link_status = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
	/* If we have a copper PHY then we only want to go out to the PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
	 * registers to see if Auto-Neg has completed and/or if our link
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	 * status has changed.  The get_link_status flag will be set if we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	 * receive a Link Status Change interrupt or we have Rx Sequence
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
	 * Errors.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		/* First we want to see if the MII Status Register reports
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
		 * link.  If so, then we want to get the current speed/duplex
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		 * of the PHY.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		 * Read the register twice since the link bit is sticky.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		if (phy_data & MII_SR_LINK_STATUS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
			hw->get_link_status = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
			/* Check if there was DownShift, must be checked immediately after
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
			 * link-up */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
			e1000_check_downshift(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
			/* If we are on 82544 or 82543 silicon and speed/duplex
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
			 * are forced to 10H or 10F, then we will implement the polarity
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
			 * reversal workaround.  We disable interrupts first, and upon
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
			 * returning, place the devices interrupt state to its previous
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
			 * value except for the link status change interrupt which will
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
			 * happen due to the execution of this workaround.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
			if ((hw->mac_type == e1000_82544
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
			     || hw->mac_type == e1000_82543) && (!hw->autoneg)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
			    && (hw->forced_speed_duplex == e1000_10_full
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
				|| hw->forced_speed_duplex == e1000_10_half)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
				ew32(IMC, 0xffffffff);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
				ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
				    e1000_polarity_reversal_workaround(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
				icr = er32(ICR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
				ew32(ICS, (icr & ~E1000_ICS_LSC));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
				ew32(IMS, IMS_ENABLE_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
			/* No link detected */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
			e1000_config_dsp_after_link_change(hw, false);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
			return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
		/* If we are forcing speed/duplex, then we simply return since
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
		 * we have already determined whether we have link or not.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
		if (!hw->autoneg)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
			return -E1000_ERR_CONFIG;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
		/* optimize the dsp settings for the igp phy */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
		e1000_config_dsp_after_link_change(hw, true);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
		/* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
		 * have Si on board that is 82544 or newer, Auto
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
		 * Speed Detection takes care of MAC speed/duplex
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		 * configuration.  So we only need to configure Collision
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
		 * Distance in the MAC.  Otherwise, we need to force
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
		 * speed/duplex on the MAC to the current PHY speed/duplex
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
		 * settings.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		if (hw->mac_type >= e1000_82544)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
			e1000_config_collision_dist(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
		else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
			ret_val = e1000_config_mac_to_phy(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
			if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
				e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
				    ("Error configuring MAC to PHY settings\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
		/* Configure Flow Control now that Auto-Neg has completed. First, we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
		 * need to restore the desired flow control settings because we may
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
		 * have had to re-autoneg with a different link partner.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
		ret_val = e1000_config_fc_after_link_up(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
			e_dbg("Error configuring flow control\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
		/* At this point we know that we are on copper and we have
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
		 * auto-negotiated link.  These are conditions for checking the link
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
		 * partner capability register.  We use the link speed to determine if
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
		 * TBI compatibility needs to be turned on or off.  If the link is not
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
		 * at gigabit speed, then TBI compatibility is not needed.  If we are
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
		 * at gigabit speed, we turn on TBI compatibility.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
		if (hw->tbi_compatibility_en) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
			u16 speed, duplex;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
			if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
				e_dbg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
				    ("Error getting link speed and duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
			if (speed != SPEED_1000) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
				/* If link speed is not set to gigabit speed, we do not need
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
				 * to enable TBI compatibility.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
				 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
				if (hw->tbi_compatibility_on) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
					/* If we previously were in the mode, turn it off. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
					rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
					rctl &= ~E1000_RCTL_SBP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
					ew32(RCTL, rctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
					hw->tbi_compatibility_on = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
				}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
			} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
				/* If TBI compatibility is was previously off, turn it on. For
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
				 * compatibility with a TBI link partner, we will store bad
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
				 * packets. Some frames have an additional byte on the end and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
				 * will look like CRC errors to to the hardware.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
				 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
				if (!hw->tbi_compatibility_on) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
					hw->tbi_compatibility_on = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
					rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
					rctl |= E1000_RCTL_SBP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
					ew32(RCTL, rctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
				}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
	if ((hw->media_type == e1000_media_type_fiber) ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
	    (hw->media_type == e1000_media_type_internal_serdes))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
		e1000_check_for_serdes_link_generic(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
 * e1000_get_speed_and_duplex
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
 * @speed: Speed of the connection
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
 * @duplex: Duplex setting of the connection
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
 * Detects the current speed and duplex settings of the hardware.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	u32 status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	e_dbg("e1000_get_speed_and_duplex");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
	if (hw->mac_type >= e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
		status = er32(STATUS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		if (status & E1000_STATUS_SPEED_1000) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
			*speed = SPEED_1000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
			e_dbg("1000 Mbs, ");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
		} else if (status & E1000_STATUS_SPEED_100) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
			*speed = SPEED_100;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
			e_dbg("100 Mbs, ");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
			*speed = SPEED_10;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
			e_dbg("10 Mbs, ");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
		if (status & E1000_STATUS_FD) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
			*duplex = FULL_DUPLEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
			e_dbg("Full Duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
			*duplex = HALF_DUPLEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
			e_dbg(" Half Duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
		e_dbg("1000 Mbs, Full Duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		*speed = SPEED_1000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
		*duplex = FULL_DUPLEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
	/* IGP01 PHY may advertise full duplex operation after speed downgrade even
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	 * if it is operating at half duplex.  Here we set the duplex settings to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	 * match the duplex in the link partner's capabilities.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
		ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		if (!(phy_data & NWAY_ER_LP_NWAY_CAPS))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
			*duplex = HALF_DUPLEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
		else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
			    e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
			if ((*speed == SPEED_100
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			     && !(phy_data & NWAY_LPAR_100TX_FD_CAPS))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
			    || (*speed == SPEED_10
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
				&& !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
				*duplex = HALF_DUPLEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
 * e1000_wait_autoneg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
 * Blocks until autoneg completes or times out (~4.5 seconds)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
static s32 e1000_wait_autoneg(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	u16 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	e_dbg("e1000_wait_autoneg");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
	e_dbg("Waiting for Auto-Neg to complete.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	/* We will wait for autoneg to complete or 4.5 seconds to expire. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
	for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
		/* Read the MII Status Register and wait for Auto-Neg
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
		 * Complete bit to be set.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
		if (phy_data & MII_SR_AUTONEG_COMPLETE) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
			return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		msleep(100);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
 * e1000_raise_mdi_clk - Raises the Management Data Clock
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
 * @ctrl: Device control register's current value
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
	/* Raise the clock input to the Management Data Clock (by setting the MDC
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	 * bit), and then delay 10 microseconds.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	ew32(CTRL, (*ctrl | E1000_CTRL_MDC));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	udelay(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
 * e1000_lower_mdi_clk - Lowers the Management Data Clock
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
 * @ctrl: Device control register's current value
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
	/* Lower the clock input to the Management Data Clock (by clearing the MDC
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
	 * bit), and then delay 10 microseconds.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	ew32(CTRL, (*ctrl & ~E1000_CTRL_MDC));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
	udelay(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
 * e1000_shift_out_mdi_bits - Shifts data bits out to the PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
 * @data: Data to send out to the PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
 * @count: Number of bits to shift out
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
 * Bits are shifted out in MSB to LSB order.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data, u16 count)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
	u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	u32 mask;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	/* We need to shift "count" number of bits out to the PHY. So, the value
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
	 * in the "data" parameter will be shifted out to the PHY one bit at a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	 * time. In order to do this, "data" must be broken down into bits.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	mask = 0x01;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	mask <<= (count - 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
	ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	/* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	while (mask) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
		/* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
		 * then raising and lowering the Management Data Clock. A "0" is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
		 * shifted out to the PHY by setting the MDIO bit to "0" and then
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
		 * raising and lowering the clock.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
		if (data & mask)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
			ctrl |= E1000_CTRL_MDIO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
		else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
			ctrl &= ~E1000_CTRL_MDIO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
		ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
		udelay(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
		e1000_raise_mdi_clk(hw, &ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		e1000_lower_mdi_clk(hw, &ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
		mask = mask >> 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
 * e1000_shift_in_mdi_bits - Shifts data bits in from the PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
 * Bits are shifted in in MSB to LSB order.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
	u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	u16 data = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	u8 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
	/* In order to read a register from the PHY, we need to shift in a total
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
	 * of 18 bits from the PHY. The first two bit (turnaround) times are used
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	 * to avoid contention on the MDIO pin when a read operation is performed.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
	 * These two bits are ignored by us and thrown away. Bits are "shifted in"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	 * by raising the input to the Management Data Clock (setting the MDC bit),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	 * and then reading the value of the MDIO bit.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
	/* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
	ctrl &= ~E1000_CTRL_MDIO_DIR;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
	ctrl &= ~E1000_CTRL_MDIO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
	ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
	/* Raise and Lower the clock before reading in the data. This accounts for
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	 * the turnaround bits. The first clock occurred when we clocked out the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
	 * last bit of the Register Address.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	e1000_raise_mdi_clk(hw, &ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	e1000_lower_mdi_clk(hw, &ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
	for (data = 0, i = 0; i < 16; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
		data = data << 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		e1000_raise_mdi_clk(hw, &ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
		ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		/* Check to see if we shifted in a "1". */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
		if (ctrl & E1000_CTRL_MDIO)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
			data |= 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
		e1000_lower_mdi_clk(hw, &ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
	e1000_raise_mdi_clk(hw, &ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	e1000_lower_mdi_clk(hw, &ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
	return data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
 * e1000_read_phy_reg - read a phy register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
 * @reg_addr: address of the PHY register to read
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
 * Reads the value from a PHY register, if the value is on a specific non zero
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
 * page, sets the page first.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
	u32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
	e_dbg("e1000_read_phy_reg");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
	if ((hw->phy_type == e1000_phy_igp) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
						 (u16) reg_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
	ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
					phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
	return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
				 u16 *phy_data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
	u32 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
	u32 mdic = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	const u32 phy_addr = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
	e_dbg("e1000_read_phy_reg_ex");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
		e_dbg("PHY Address %d is out of range\n", reg_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
		return -E1000_ERR_PARAM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	if (hw->mac_type > e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
		/* Set up Op-code, Phy Address, and register address in the MDI
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
		 * Control register.  The MAC will take care of interfacing with the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
		 * PHY to retrieve the desired data.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
		mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
			(phy_addr << E1000_MDIC_PHY_SHIFT) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
			(E1000_MDIC_OP_READ));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
		ew32(MDIC, mdic);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
		/* Poll the ready bit to see if the MDI read completed */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
		for (i = 0; i < 64; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
			udelay(50);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
			mdic = er32(MDIC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
			if (mdic & E1000_MDIC_READY)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
		if (!(mdic & E1000_MDIC_READY)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
			e_dbg("MDI Read did not complete\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
			return -E1000_ERR_PHY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
		if (mdic & E1000_MDIC_ERROR) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
			e_dbg("MDI Error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
			return -E1000_ERR_PHY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		*phy_data = (u16) mdic;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		/* We must first send a preamble through the MDIO pin to signal the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
		 * beginning of an MII instruction.  This is done by sending 32
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		 * consecutive "1" bits.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
		/* Now combine the next few fields that are required for a read
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
		 * operation.  We use this method instead of calling the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
		 * e1000_shift_out_mdi_bits routine five different times. The format of
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
		 * a MII read instruction consists of a shift out of 14 bits and is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
		 * defined as follows:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		 *    <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		 * followed by a shift in of 18 bits.  This first two bits shifted in
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
		 * are TurnAround bits used to avoid contention on the MDIO pin when a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
		 * READ operation is performed.  These two bits are thrown away
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
		 * followed by a shift in of 16 bits which contains the desired data.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
		mdic = ((reg_addr) | (phy_addr << 5) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
			(PHY_OP_READ << 10) | (PHY_SOF << 12));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
		e1000_shift_out_mdi_bits(hw, mdic, 14);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
		/* Now that we've shifted out the read command to the MII, we need to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
		 * "shift in" the 16-bit value (18 total bits) of the requested PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		 * register address.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
		*phy_data = e1000_shift_in_mdi_bits(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
 * e1000_write_phy_reg - write a phy register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
 * @reg_addr: address of the PHY register to write
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
 * @data: data to write to the PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
 * Writes a value to a PHY register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	u32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	e_dbg("e1000_write_phy_reg");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	if ((hw->phy_type == e1000_phy_igp) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
						 (u16) reg_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
	ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
					 phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
	return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
				  u16 phy_data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
	u32 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	u32 mdic = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
	const u32 phy_addr = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
	e_dbg("e1000_write_phy_reg_ex");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		e_dbg("PHY Address %d is out of range\n", reg_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
		return -E1000_ERR_PARAM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
	if (hw->mac_type > e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
		/* Set up Op-code, Phy Address, register address, and data intended
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
		 * for the PHY register in the MDI Control register.  The MAC will take
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
		 * care of interfacing with the PHY to send the desired data.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
		mdic = (((u32) phy_data) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
			(reg_addr << E1000_MDIC_REG_SHIFT) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
			(phy_addr << E1000_MDIC_PHY_SHIFT) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
			(E1000_MDIC_OP_WRITE));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
		ew32(MDIC, mdic);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
		/* Poll the ready bit to see if the MDI read completed */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
		for (i = 0; i < 641; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
			udelay(5);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
			mdic = er32(MDIC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
			if (mdic & E1000_MDIC_READY)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
		if (!(mdic & E1000_MDIC_READY)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
			e_dbg("MDI Write did not complete\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
			return -E1000_ERR_PHY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
		/* We'll need to use the SW defined pins to shift the write command
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
		 * out to the PHY. We first send a preamble to the PHY to signal the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
		 * beginning of the MII instruction.  This is done by sending 32
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
		 * consecutive "1" bits.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
		/* Now combine the remaining required fields that will indicate a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
		 * write operation. We use this method instead of calling the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
		 * e1000_shift_out_mdi_bits routine for each field in the command. The
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
		 * format of a MII write instruction is as follows:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
		 * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
			(PHY_OP_WRITE << 12) | (PHY_SOF << 14));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
		mdic <<= 16;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		mdic |= (u32) phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		e1000_shift_out_mdi_bits(hw, mdic, 32);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
 * e1000_phy_hw_reset - reset the phy, hardware style
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
 * Returns the PHY to the power-on reset state
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
s32 e1000_phy_hw_reset(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
	u32 ctrl, ctrl_ext;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
	u32 led_ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	e_dbg("e1000_phy_hw_reset");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	e_dbg("Resetting Phy...\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
	if (hw->mac_type > e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
		/* Read the device control register and assert the E1000_CTRL_PHY_RST
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
		 * bit. Then, take it out of reset.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
		 * For e1000 hardware, we delay for 10ms between the assert
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
		 * and deassert.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		msleep(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
		/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
		 * bit to put the PHY into reset. Then, take it out of reset.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		ctrl_ext = er32(CTRL_EXT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		ew32(CTRL_EXT, ctrl_ext);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		msleep(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
		ew32(CTRL_EXT, ctrl_ext);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	udelay(150);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
		/* Configure activity LED after PHY reset */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		led_ctrl = er32(LEDCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
		ew32(LEDCTL, led_ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
	/* Wait for FW to finish PHY configuration. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	ret_val = e1000_get_phy_cfg_done(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	if (ret_val != E1000_SUCCESS)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
	return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
 * e1000_phy_reset - reset the phy to commit settings
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
 * Resets the PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
 * Sets bit 15 of the MII Control register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
s32 e1000_phy_reset(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
	e_dbg("e1000_phy_reset");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
	switch (hw->phy_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
	case e1000_phy_igp:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
		ret_val = e1000_phy_hw_reset(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
		ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		phy_data |= MII_CR_RESET;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
		ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
		udelay(1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	if (hw->phy_type == e1000_phy_igp)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
		e1000_phy_init_script(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
 * e1000_detect_gig_phy - check the phy type
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
 * Probes the expected PHY address for known PHY IDs
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
static s32 e1000_detect_gig_phy(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	s32 phy_init_status, ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
	u16 phy_id_high, phy_id_low;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	bool match = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
	e_dbg("e1000_detect_gig_phy");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
	if (hw->phy_id != 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
	/* Read the PHY ID Registers to identify which PHY is onboard. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
	ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
	hw->phy_id = (u32) (phy_id_high << 16);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
	udelay(20);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
	hw->phy_id |= (u32) (phy_id_low & PHY_REVISION_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	hw->phy_revision = (u32) phy_id_low & ~PHY_REVISION_MASK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	case e1000_82543:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
		if (hw->phy_id == M88E1000_E_PHY_ID)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
			match = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
	case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
		if (hw->phy_id == M88E1000_I_PHY_ID)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
			match = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
	case e1000_82540:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
	case e1000_82545:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	case e1000_82545_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	case e1000_82546:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	case e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		if (hw->phy_id == M88E1011_I_PHY_ID)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
			match = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
	case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
	case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	case e1000_82547:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	case e1000_82547_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
		if (hw->phy_id == IGP01E1000_I_PHY_ID)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
			match = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
		e_dbg("Invalid MAC type %d\n", hw->mac_type);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
		return -E1000_ERR_CONFIG;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	phy_init_status = e1000_set_phy_type(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	if ((match) && (phy_init_status == E1000_SUCCESS)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		e_dbg("PHY ID 0x%X detected\n", hw->phy_id);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	e_dbg("Invalid PHY ID 0x%X\n", hw->phy_id);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	return -E1000_ERR_PHY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
 * e1000_phy_reset_dsp - reset DSP
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
 * Resets the PHY's DSP
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
	e_dbg("e1000_phy_reset_dsp");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	do {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
		ret_val = e1000_write_phy_reg(hw, 29, 0x001d);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
		ret_val = e1000_write_phy_reg(hw, 30, 0x00c1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
		ret_val = e1000_write_phy_reg(hw, 30, 0x0000);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
		ret_val = E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
	} while (0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
 * e1000_phy_igp_get_info - get igp specific registers
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
 * @phy_info: PHY information structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
 * Get PHY information from various PHY registers for igp PHY only.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
				  struct e1000_phy_info *phy_info)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	u16 phy_data, min_length, max_length, average;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
	e1000_rev_polarity polarity;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
	e_dbg("e1000_phy_igp_get_info");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
	/* The downshift status is checked only once, after link is established,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
	 * and it stored in the hw->speed_downgraded parameter. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	phy_info->downshift = (e1000_downshift) hw->speed_downgraded;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
	/* IGP01E1000 does not need to support it. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
	/* IGP01E1000 always correct polarity reversal */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
	phy_info->polarity_correction = e1000_polarity_reversal_enabled;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
	/* Check polarity status */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	ret_val = e1000_check_polarity(hw, &polarity);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
	phy_info->cable_polarity = polarity;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	phy_info->mdix_mode =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	    (e1000_auto_x_mode) ((phy_data & IGP01E1000_PSSR_MDIX) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
				 IGP01E1000_PSSR_MDIX_SHIFT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
	if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
		/* Local/Remote Receiver Information are only valid at 1000 Mbps */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
		phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
		/* Get cable length */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
		ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
		/* Translate to old method */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
		average = (max_length + min_length) / 2;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
		if (average <= e1000_igp_cable_length_50)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
			phy_info->cable_length = e1000_cable_length_50;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
		else if (average <= e1000_igp_cable_length_80)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
			phy_info->cable_length = e1000_cable_length_50_80;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
		else if (average <= e1000_igp_cable_length_110)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
			phy_info->cable_length = e1000_cable_length_80_110;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
		else if (average <= e1000_igp_cable_length_140)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
			phy_info->cable_length = e1000_cable_length_110_140;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
		else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
			phy_info->cable_length = e1000_cable_length_140;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
 * e1000_phy_m88_get_info - get m88 specific registers
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
 * @phy_info: PHY information structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
 * Get PHY information from various PHY registers for m88 PHY only.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
				  struct e1000_phy_info *phy_info)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	e1000_rev_polarity polarity;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	e_dbg("e1000_phy_m88_get_info");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	/* The downshift status is checked only once, after link is established,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	 * and it stored in the hw->speed_downgraded parameter. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	phy_info->downshift = (e1000_downshift) hw->speed_downgraded;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	phy_info->extended_10bt_distance =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	    ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	     M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	    e1000_10bt_ext_dist_enable_lower :
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	    e1000_10bt_ext_dist_enable_normal;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	phy_info->polarity_correction =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	    ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	     M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	    e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	/* Check polarity status */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	ret_val = e1000_check_polarity(hw, &polarity);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	phy_info->cable_polarity = polarity;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	phy_info->mdix_mode =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
	    (e1000_auto_x_mode) ((phy_data & M88E1000_PSSR_MDIX) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
				 M88E1000_PSSR_MDIX_SHIFT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
		/* Cable Length Estimation and Local/Remote Receiver Information
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
		 * are only valid at 1000 Mbps.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
		phy_info->cable_length =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		    (e1000_cable_length) ((phy_data &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
					   M88E1000_PSSR_CABLE_LENGTH) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
					  M88E1000_PSSR_CABLE_LENGTH_SHIFT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
		phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
 * e1000_phy_get_info - request phy info
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
 * @phy_info: PHY information structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
 * Get PHY information from various PHY registers
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
s32 e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	e_dbg("e1000_phy_get_info");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
	phy_info->cable_length = e1000_cable_length_undefined;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
	phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
	phy_info->cable_polarity = e1000_rev_polarity_undefined;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	phy_info->downshift = e1000_downshift_undefined;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	phy_info->polarity_correction = e1000_polarity_reversal_undefined;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
	phy_info->mdix_mode = e1000_auto_x_mode_undefined;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	phy_info->local_rx = e1000_1000t_rx_status_undefined;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	phy_info->remote_rx = e1000_1000t_rx_status_undefined;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
	if (hw->media_type != e1000_media_type_copper) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
		e_dbg("PHY info is only valid for copper media\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
		return -E1000_ERR_CONFIG;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
	ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
	ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
	if ((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
		e_dbg("PHY info is only valid if link is up\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
		return -E1000_ERR_CONFIG;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	if (hw->phy_type == e1000_phy_igp)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
		return e1000_phy_igp_get_info(hw, phy_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
		return e1000_phy_m88_get_info(hw, phy_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
s32 e1000_validate_mdi_setting(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	e_dbg("e1000_validate_mdi_settings");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	if (!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
		e_dbg("Invalid MDI setting detected\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
		hw->mdix = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
		return -E1000_ERR_CONFIG;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
 * e1000_init_eeprom_params - initialize sw eeprom vars
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
 * Sets up eeprom variables in the hw struct.  Must be called after mac_type
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
 * is configured.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
s32 e1000_init_eeprom_params(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	u32 eecd = er32(EECD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	s32 ret_val = E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	u16 eeprom_size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	e_dbg("e1000_init_eeprom_params");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
	case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
	case e1000_82543:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
		eeprom->type = e1000_eeprom_microwire;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
		eeprom->word_size = 64;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
		eeprom->opcode_bits = 3;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
		eeprom->address_bits = 6;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
		eeprom->delay_usec = 50;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
	case e1000_82540:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	case e1000_82545:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	case e1000_82545_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	case e1000_82546:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	case e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
		eeprom->type = e1000_eeprom_microwire;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		eeprom->opcode_bits = 3;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
		eeprom->delay_usec = 50;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
		if (eecd & E1000_EECD_SIZE) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
			eeprom->word_size = 256;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
			eeprom->address_bits = 8;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
			eeprom->word_size = 64;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
			eeprom->address_bits = 6;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	case e1000_82547:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	case e1000_82547_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
		if (eecd & E1000_EECD_TYPE) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
			eeprom->type = e1000_eeprom_spi;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
			eeprom->opcode_bits = 8;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
			eeprom->delay_usec = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
			if (eecd & E1000_EECD_ADDR_BITS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
				eeprom->page_size = 32;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
				eeprom->address_bits = 16;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
			} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
				eeprom->page_size = 8;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
				eeprom->address_bits = 8;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
			eeprom->type = e1000_eeprom_microwire;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
			eeprom->opcode_bits = 3;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
			eeprom->delay_usec = 50;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
			if (eecd & E1000_EECD_ADDR_BITS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
				eeprom->word_size = 256;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
				eeprom->address_bits = 8;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
			} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
				eeprom->word_size = 64;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
				eeprom->address_bits = 6;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	if (eeprom->type == e1000_eeprom_spi) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
		/* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
		 * 32KB (incremented by powers of 2).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		/* Set to default value for initial eeprom read. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		eeprom->word_size = 64;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
		ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
		eeprom_size =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
		    (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
		/* 256B eeprom size was not supported in earlier hardware, so we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
		 * bump eeprom_size up one to ensure that "1" (which maps to 256B)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
		 * is never the result used in the shifting logic below. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
		if (eeprom_size)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
			eeprom_size++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
		eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
 * e1000_raise_ee_clk - Raises the EEPROM's clock input.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
 * @eecd: EECD's current value
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
	/* Raise the clock input to the EEPROM (by setting the SK bit), and then
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
	 * wait <delay> microseconds.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
	*eecd = *eecd | E1000_EECD_SK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	ew32(EECD, *eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	udelay(hw->eeprom.delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
 * e1000_lower_ee_clk - Lowers the EEPROM's clock input.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
 * @eecd: EECD's current value
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
	 * wait 50 microseconds.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	*eecd = *eecd & ~E1000_EECD_SK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	ew32(EECD, *eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	udelay(hw->eeprom.delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
 * e1000_shift_out_ee_bits - Shift data bits out to the EEPROM.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
 * @data: data to send to the EEPROM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
 * @count: number of bits to shift out
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data, u16 count)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	u32 eecd;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	u32 mask;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
	/* We need to shift "count" bits out to the EEPROM. So, value in the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
	 * "data" parameter will be shifted out to the EEPROM one bit at a time.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	 * In order to do this, "data" must be broken down into bits.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
	mask = 0x01 << (count - 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	eecd = er32(EECD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
	if (eeprom->type == e1000_eeprom_microwire) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
		eecd &= ~E1000_EECD_DO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	} else if (eeprom->type == e1000_eeprom_spi) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
		eecd |= E1000_EECD_DO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	do {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		 * and then raising and then lowering the clock (the SK bit controls
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		 * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
		 * by setting "DI" to "0" and then raising and then lowering the clock.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		eecd &= ~E1000_EECD_DI;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
		if (data & mask)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
			eecd |= E1000_EECD_DI;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
		udelay(eeprom->delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
		e1000_raise_ee_clk(hw, &eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
		e1000_lower_ee_clk(hw, &eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
		mask = mask >> 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
	} while (mask);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	/* We leave the "DI" bit set to "0" when we leave this routine. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	eecd &= ~E1000_EECD_DI;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
 * e1000_shift_in_ee_bits - Shift data bits in from the EEPROM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
 * @count: number of bits to shift in
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	u32 eecd;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	u32 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	u16 data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	/* In order to read a register from the EEPROM, we need to shift 'count'
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
	 * bits in from the EEPROM. Bits are "shifted in" by raising the clock
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	 * input to the EEPROM (setting the SK bit), and then reading the value of
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	 * the "DO" bit.  During this "shifting in" process the "DI" bit should
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
	 * always be clear.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
	eecd = er32(EECD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
	data = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
	for (i = 0; i < count; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
		data = data << 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
		e1000_raise_ee_clk(hw, &eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
		eecd = er32(EECD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
		eecd &= ~(E1000_EECD_DI);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
		if (eecd & E1000_EECD_DO)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
			data |= 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
		e1000_lower_ee_clk(hw, &eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
	return data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
 * e1000_acquire_eeprom - Prepares EEPROM for access
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
 * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
 * function should be called before issuing a command to the EEPROM.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
static s32 e1000_acquire_eeprom(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	u32 eecd, i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
	e_dbg("e1000_acquire_eeprom");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
	eecd = er32(EECD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
	/* Request EEPROM Access */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
	if (hw->mac_type > e1000_82544) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
		eecd |= E1000_EECD_REQ;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
		eecd = er32(EECD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		while ((!(eecd & E1000_EECD_GNT)) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
		       (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
			i++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
			udelay(5);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
			eecd = er32(EECD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
		if (!(eecd & E1000_EECD_GNT)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
			eecd &= ~E1000_EECD_REQ;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
			ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
			e_dbg("Could not acquire EEPROM grant\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
			return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
	/* Setup EEPROM for Read/Write */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	if (eeprom->type == e1000_eeprom_microwire) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
		/* Clear SK and DI */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
		/* Set CS */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
		eecd |= E1000_EECD_CS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	} else if (eeprom->type == e1000_eeprom_spi) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
		/* Clear SK and CS */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
		udelay(1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
 * e1000_standby_eeprom - Returns EEPROM to a "standby" state
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
static void e1000_standby_eeprom(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	u32 eecd;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
	eecd = er32(EECD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	if (eeprom->type == e1000_eeprom_microwire) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
		udelay(eeprom->delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
		/* Clock high */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
		eecd |= E1000_EECD_SK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
		udelay(eeprom->delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
		/* Select EEPROM */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
		eecd |= E1000_EECD_CS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
		udelay(eeprom->delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
		/* Clock low */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
		eecd &= ~E1000_EECD_SK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
		udelay(eeprom->delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
	} else if (eeprom->type == e1000_eeprom_spi) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
		/* Toggle CS to flush commands */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
		eecd |= E1000_EECD_CS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
		udelay(eeprom->delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
		eecd &= ~E1000_EECD_CS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
		udelay(eeprom->delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
 * e1000_release_eeprom - drop chip select
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
 * Terminates a command by inverting the EEPROM's chip select pin
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
static void e1000_release_eeprom(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	u32 eecd;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	e_dbg("e1000_release_eeprom");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	eecd = er32(EECD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	if (hw->eeprom.type == e1000_eeprom_spi) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
		eecd |= E1000_EECD_CS;	/* Pull CS high */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
		eecd &= ~E1000_EECD_SK;	/* Lower SCK */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
		udelay(hw->eeprom.delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
	} else if (hw->eeprom.type == e1000_eeprom_microwire) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
		/* cleanup eeprom */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
		/* CS on Microwire is active-high */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
		/* Rising edge of clock */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
		eecd |= E1000_EECD_SK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
		udelay(hw->eeprom.delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
		/* Falling edge of clock */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
		eecd &= ~E1000_EECD_SK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
		udelay(hw->eeprom.delay_usec);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
	/* Stop requesting EEPROM access */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	if (hw->mac_type > e1000_82544) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
		eecd &= ~E1000_EECD_REQ;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
		ew32(EECD, eecd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
 * e1000_spi_eeprom_ready - Reads a 16 bit word from the EEPROM.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
	u16 retry_count = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	u8 spi_stat_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
	e_dbg("e1000_spi_eeprom_ready");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
	/* Read "Status Register" repeatedly until the LSB is cleared.  The
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	 * EEPROM will signal that the command has been completed by clearing
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
	 * bit 0 of the internal status register.  If it's not cleared within
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	 * 5 milliseconds, then error out.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
	retry_count = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	do {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
		e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
					hw->eeprom.opcode_bits);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
		spi_stat_reg = (u8) e1000_shift_in_ee_bits(hw, 8);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
		if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
		udelay(5);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
		retry_count += 5;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
		e1000_standby_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
	} while (retry_count < EEPROM_MAX_RETRY_SPI);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
	/* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
	 * only 0-5mSec on 5V devices)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
	if (retry_count >= EEPROM_MAX_RETRY_SPI) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
		e_dbg("SPI EEPROM Status error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
		return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
 * e1000_read_eeprom - Reads a 16 bit word from the EEPROM.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
 * @offset: offset of  word in the EEPROM to read
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
 * @data: word read from the EEPROM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
 * @words: number of words to read
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
	s32 ret;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	spin_lock(&e1000_eeprom_lock);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
	ret = e1000_do_read_eeprom(hw, offset, words, data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	spin_unlock(&e1000_eeprom_lock);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
	return ret;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
				u16 *data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
	u32 i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
	e_dbg("e1000_read_eeprom");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
	/* If eeprom is not yet detected, do so now */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
	if (eeprom->word_size == 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
		e1000_init_eeprom_params(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
	/* A check for invalid values:  offset too large, too many words, and not
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
	 * enough words.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
	if ((offset >= eeprom->word_size)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
	    || (words > eeprom->word_size - offset) || (words == 0)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
		e_dbg("\"words\" parameter out of bounds. Words = %d,"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
		      "size = %d\n", offset, eeprom->word_size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
		return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
	/* EEPROM's that don't use EERD to read require us to bit-bang the SPI
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
	 * directly. In this case, we need to acquire the EEPROM so that
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
	 * FW or other port software does not interrupt.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
	/* Prepare the EEPROM for bit-bang reading */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
		return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
	/* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
	 * acquired the EEPROM at this point, so any returns should release it */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
	if (eeprom->type == e1000_eeprom_spi) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
		u16 word_in;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
		u8 read_opcode = EEPROM_READ_OPCODE_SPI;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
		if (e1000_spi_eeprom_ready(hw)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
			e1000_release_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
			return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
		e1000_standby_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
		/* Some SPI eeproms use the 8th address bit embedded in the opcode */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
		if ((eeprom->address_bits == 8) && (offset >= 128))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
			read_opcode |= EEPROM_A8_OPCODE_SPI;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
		/* Send the READ command (opcode + addr)  */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
		e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
		e1000_shift_out_ee_bits(hw, (u16) (offset * 2),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
					eeprom->address_bits);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
		/* Read the data.  The address of the eeprom internally increments with
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
		 * each byte (spi) being read, saving on the overhead of eeprom setup
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
		 * and tear-down.  The address counter will roll over if reading beyond
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
		 * the size of the eeprom, thus allowing the entire memory to be read
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
		 * starting from any offset. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
		for (i = 0; i < words; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
			word_in = e1000_shift_in_ee_bits(hw, 16);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
			data[i] = (word_in >> 8) | (word_in << 8);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
	} else if (eeprom->type == e1000_eeprom_microwire) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
		for (i = 0; i < words; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
			/* Send the READ command (opcode + addr)  */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
			e1000_shift_out_ee_bits(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
						EEPROM_READ_OPCODE_MICROWIRE,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
						eeprom->opcode_bits);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
			e1000_shift_out_ee_bits(hw, (u16) (offset + i),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
						eeprom->address_bits);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
			/* Read the data.  For microwire, each word requires the overhead
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
			 * of eeprom setup and tear-down. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
			data[i] = e1000_shift_in_ee_bits(hw, 16);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
			e1000_standby_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
	/* End this read operation */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
	e1000_release_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
 * e1000_validate_eeprom_checksum - Verifies that the EEPROM has a valid checksum
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
 * Reads the first 64 16 bit words of the EEPROM and sums the values read.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
 * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
 * valid.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
	u16 checksum = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	u16 i, eeprom_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	e_dbg("e1000_validate_eeprom_checksum");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
		if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
			e_dbg("EEPROM Read Error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
			return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
		checksum += eeprom_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
	if (checksum == (u16) EEPROM_SUM)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
	else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
		e_dbg("EEPROM Checksum Invalid\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
		return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
 * e1000_update_eeprom_checksum - Calculates/writes the EEPROM checksum
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
 * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
 * Writes the difference to word offset 63 of the EEPROM.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
s32 e1000_update_eeprom_checksum(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
	u16 checksum = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
	u16 i, eeprom_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	e_dbg("e1000_update_eeprom_checksum");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
	for (i = 0; i < EEPROM_CHECKSUM_REG; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
		if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
			e_dbg("EEPROM Read Error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
			return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
		checksum += eeprom_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
	checksum = (u16) EEPROM_SUM - checksum;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
		e_dbg("EEPROM Write Error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
		return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
 * e1000_write_eeprom - write words to the different EEPROM types.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
 * @offset: offset within the EEPROM to be written to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
 * @words: number of words to write
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
 * @data: 16 bit word to be written to the EEPROM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
 * If e1000_update_eeprom_checksum is not called after this function, the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
 * EEPROM will most likely contain an invalid checksum.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
	s32 ret;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	spin_lock(&e1000_eeprom_lock);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
	ret = e1000_do_write_eeprom(hw, offset, words, data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	spin_unlock(&e1000_eeprom_lock);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
	return ret;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
				 u16 *data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	s32 status = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	e_dbg("e1000_write_eeprom");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
	/* If eeprom is not yet detected, do so now */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
	if (eeprom->word_size == 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		e1000_init_eeprom_params(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
	/* A check for invalid values:  offset too large, too many words, and not
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
	 * enough words.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
	if ((offset >= eeprom->word_size)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
	    || (words > eeprom->word_size - offset) || (words == 0)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
		e_dbg("\"words\" parameter out of bounds\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
		return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
	/* Prepare the EEPROM for writing  */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
		return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
	if (eeprom->type == e1000_eeprom_microwire) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
		status = e1000_write_eeprom_microwire(hw, offset, words, data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
		status = e1000_write_eeprom_spi(hw, offset, words, data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
		msleep(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
	/* Done with writing */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
	e1000_release_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	return status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
 * e1000_write_eeprom_spi - Writes a 16 bit word to a given offset in an SPI EEPROM.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
 * @offset: offset within the EEPROM to be written to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
 * @words: number of words to write
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
 * @data: pointer to array of 8 bit words to be written to the EEPROM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset, u16 words,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
				  u16 *data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
	u16 widx = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	e_dbg("e1000_write_eeprom_spi");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
	while (widx < words) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
		u8 write_opcode = EEPROM_WRITE_OPCODE_SPI;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
		if (e1000_spi_eeprom_ready(hw))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
			return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
		e1000_standby_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
		/*  Send the WRITE ENABLE command (8 bit opcode )  */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
		e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
					eeprom->opcode_bits);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
		e1000_standby_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
		/* Some SPI eeproms use the 8th address bit embedded in the opcode */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
		if ((eeprom->address_bits == 8) && (offset >= 128))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
			write_opcode |= EEPROM_A8_OPCODE_SPI;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
		/* Send the Write command (8-bit opcode + addr) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
		e1000_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
		e1000_shift_out_ee_bits(hw, (u16) ((offset + widx) * 2),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
					eeprom->address_bits);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
		/* Send the data */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		/* Loop to allow for up to whole page write (32 bytes) of eeprom */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
		while (widx < words) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
			u16 word_out = data[widx];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
			word_out = (word_out >> 8) | (word_out << 8);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
			e1000_shift_out_ee_bits(hw, word_out, 16);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
			widx++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
			/* Some larger eeprom sizes are capable of a 32-byte PAGE WRITE
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
			 * operation, while the smaller eeproms are capable of an 8-byte
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
			 * PAGE WRITE operation.  Break the inner loop to pass new address
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
			 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
			if ((((offset + widx) * 2) % eeprom->page_size) == 0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
				e1000_standby_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
 * e1000_write_eeprom_microwire - Writes a 16 bit word to a given offset in a Microwire EEPROM.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
 * @offset: offset within the EEPROM to be written to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
 * @words: number of words to write
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
 * @data: pointer to array of 8 bit words to be written to the EEPROM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
					u16 words, u16 *data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
	u32 eecd;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
	u16 words_written = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
	u16 i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
	e_dbg("e1000_write_eeprom_microwire");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
	/* Send the write enable command to the EEPROM (3-bit opcode plus
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
	 * 6/8-bit dummy address beginning with 11).  It's less work to include
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
	 * the 11 of the dummy address as part of the opcode than it is to shift
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
	 * it over the correct number of bits for the address.  This puts the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
	 * EEPROM into write/erase mode.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
	e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
				(u16) (eeprom->opcode_bits + 2));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
	/* Prepare the EEPROM */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
	e1000_standby_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
	while (words_written < words) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
		/* Send the Write command (3-bit opcode + addr) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
		e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
					eeprom->opcode_bits);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
		e1000_shift_out_ee_bits(hw, (u16) (offset + words_written),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
					eeprom->address_bits);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
		/* Send the data */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
		e1000_shift_out_ee_bits(hw, data[words_written], 16);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
		/* Toggle the CS line.  This in effect tells the EEPROM to execute
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
		 * the previous command.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
		e1000_standby_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
		/* Read DO repeatedly until it is high (equal to '1').  The EEPROM will
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
		 * signal that the command has been completed by raising the DO signal.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
		 * If DO does not go high in 10 milliseconds, then error out.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
		for (i = 0; i < 200; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
			eecd = er32(EECD);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
			if (eecd & E1000_EECD_DO)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
			udelay(50);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
		if (i == 200) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
			e_dbg("EEPROM Write did not complete\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
			return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
		/* Recover from write */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
		e1000_standby_eeprom(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		words_written++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
	/* Send the write disable command to the EEPROM (3-bit opcode plus
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
	 * 6/8-bit dummy address beginning with 10).  It's less work to include
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
	 * the 10 of the dummy address as part of the opcode than it is to shift
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
	 * it over the correct number of bits for the address.  This takes the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
	 * EEPROM out of write/erase mode.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
	e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
				(u16) (eeprom->opcode_bits + 2));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
 * e1000_read_mac_addr - read the adapters MAC from eeprom
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
 * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
 * second function of dual function devices
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
s32 e1000_read_mac_addr(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
	u16 offset;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
	u16 eeprom_data, i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	e_dbg("e1000_read_mac_addr");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
		offset = i >> 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
		if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
			e_dbg("EEPROM Read Error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
			return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
		hw->perm_mac_addr[i] = (u8) (eeprom_data & 0x00FF);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
		hw->perm_mac_addr[i + 1] = (u8) (eeprom_data >> 8);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
	case e1000_82546:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
	case e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
			hw->perm_mac_addr[5] ^= 0x01;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	for (i = 0; i < NODE_ADDRESS_SIZE; i++)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		hw->mac_addr[i] = hw->perm_mac_addr[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
 * e1000_init_rx_addrs - Initializes receive address filters.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
 * Places the MAC address in receive address register 0 and clears the rest
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
 * of the receive address registers. Clears the multicast table. Assumes
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
 * the receiver is in reset when the routine is called.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
static void e1000_init_rx_addrs(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
	u32 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
	u32 rar_num;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
	e_dbg("e1000_init_rx_addrs");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
	/* Setup the receive address. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
	e_dbg("Programming MAC Address into RAR[0]\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
	e1000_rar_set(hw, hw->mac_addr, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
	rar_num = E1000_RAR_ENTRIES;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
	/* Zero out the other 15 receive addresses. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
	e_dbg("Clearing RAR[1-15]\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
	for (i = 1; i < rar_num; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
		E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
 * e1000_hash_mc_addr - Hashes an address to determine its location in the multicast table
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
 * @mc_addr: the multicast address to hash
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
	u32 hash_value = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
	/* The portion of the address that is used for the hash table is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
	 * determined by the mc_filter_type setting.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
	switch (hw->mc_filter_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
		/* [0] [1] [2] [3] [4] [5]
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
		 * 01  AA  00  12  34  56
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
		 * LSB                 MSB
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
	case 0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		/* [47:36] i.e. 0x563 for above example address */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
		hash_value = ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
	case 1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		/* [46:35] i.e. 0xAC6 for above example address */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
		hash_value = ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
	case 2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
		/* [45:34] i.e. 0x5D8 for above example address */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
		hash_value = ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
	case 3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
		/* [43:32] i.e. 0x634 for above example address */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
		hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
	hash_value &= 0xFFF;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
	return hash_value;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
 * e1000_rar_set - Puts an ethernet address into a receive address register.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
 * @addr: Address to put into receive address register
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
 * @index: Receive address register to write
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
	u32 rar_low, rar_high;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
	/* HW expects these in little endian so we reverse the byte order
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
	 * from network order (big endian) to little endian
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
	rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
		   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
	/* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
	 * unit hang.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
	 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
	 * Description:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
	 * If there are any Rx frames queued up or otherwise present in the HW
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
	 * before RSS is enabled, and then we enable RSS, the HW Rx unit will
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
	 * hang.  To work around this issue, we have to disable receives and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
	 * flush out all Rx frames before we enable RSS. To do so, we modify we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
	 * redirect all Rx traffic to manageability and then reset the HW.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
	 * This flushes away Rx frames, and (since the redirections to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
	 * manageability persists across resets) keeps new ones from coming in
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
	 * while we work.  Then, we clear the Address Valid AV bit for all MAC
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
	 * addresses and undo the re-direction to manageability.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
	 * Now, frames are coming in again, but the MAC won't accept them, so
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
	 * far so good.  We now proceed to initialize RSS (if necessary) and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
	 * configure the Rx unit.  Last, we re-enable the AV bits and continue
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
	 * on our merry way.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
		/* Indicate to hardware the Address is Valid. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
		rar_high |= E1000_RAH_AV;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
	E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
 * e1000_write_vfta - Writes a value to the specified offset in the VLAN filter table.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
 * @offset: Offset in VLAN filer table to write
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
 * @value: Value to write into VLAN filter table
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
	u32 temp;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
	if ((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
		temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
		E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
 * e1000_clear_vfta - Clears the VLAN filer table
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
static void e1000_clear_vfta(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	u32 offset;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
	u32 vfta_value = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	u32 vfta_offset = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
	u32 vfta_bit_in_reg = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
		/* If the offset we want to clear is the same offset of the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
		 * manageability VLAN ID, then clear all bits except that of the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
		 * manageability unit */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
		vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
static s32 e1000_id_led_init(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
	u32 ledctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
	const u32 ledctl_mask = 0x000000FF;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
	u16 eeprom_data, i, temp;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
	const u16 led_mask = 0x0F;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
	e_dbg("e1000_id_led_init");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
	if (hw->mac_type < e1000_82540) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
		/* Nothing to do */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
	ledctl = er32(LEDCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
	hw->ledctl_default = ledctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
	hw->ledctl_mode1 = hw->ledctl_default;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
	hw->ledctl_mode2 = hw->ledctl_default;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
	if (e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
		e_dbg("EEPROM Read Error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
		return -E1000_ERR_EEPROM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
	if ((eeprom_data == ID_LED_RESERVED_0000) ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	    (eeprom_data == ID_LED_RESERVED_FFFF)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
		eeprom_data = ID_LED_DEFAULT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	for (i = 0; i < 4; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
		temp = (eeprom_data >> (i << 2)) & led_mask;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
		switch (temp) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		case ID_LED_ON1_DEF2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
		case ID_LED_ON1_ON2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
		case ID_LED_ON1_OFF2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
			hw->ledctl_mode1 |= ledctl_on << (i << 3);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
		case ID_LED_OFF1_DEF2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
		case ID_LED_OFF1_ON2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
		case ID_LED_OFF1_OFF2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
			hw->ledctl_mode1 |= ledctl_off << (i << 3);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
		default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
			/* Do nothing */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
		switch (temp) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
		case ID_LED_DEF1_ON2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
		case ID_LED_ON1_ON2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
		case ID_LED_OFF1_ON2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
			hw->ledctl_mode2 |= ledctl_on << (i << 3);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
		case ID_LED_DEF1_OFF2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
		case ID_LED_ON1_OFF2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
		case ID_LED_OFF1_OFF2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
			hw->ledctl_mode2 |= ledctl_off << (i << 3);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
			/* Do nothing */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
 * e1000_setup_led
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
 * Prepares SW controlable LED for use and saves the current state of the LED.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
s32 e1000_setup_led(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
	u32 ledctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
	s32 ret_val = E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
	e_dbg("e1000_setup_led");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
	case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
	case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
	case e1000_82543:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
	case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
		/* No setup necessary */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
	case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
	case e1000_82547:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
	case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
	case e1000_82547_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
		/* Turn off PHY Smart Power Down (if enabled) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
					     &hw->phy_spd_default);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
					      (u16) (hw->phy_spd_default &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
						     ~IGP01E1000_GMII_SPD));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
		/* Fall Through */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
		if (hw->media_type == e1000_media_type_fiber) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
			ledctl = er32(LEDCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
			/* Save current LEDCTL settings */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
			hw->ledctl_default = ledctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
			/* Turn off LED0 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
			ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
				    E1000_LEDCTL_LED0_BLINK |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
				    E1000_LEDCTL_LED0_MODE_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
			ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
				   E1000_LEDCTL_LED0_MODE_SHIFT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
			ew32(LEDCTL, ledctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
		} else if (hw->media_type == e1000_media_type_copper)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
			ew32(LEDCTL, hw->ledctl_mode1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
 * e1000_cleanup_led - Restores the saved state of the SW controlable LED.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
s32 e1000_cleanup_led(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
	s32 ret_val = E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	e_dbg("e1000_cleanup_led");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
	case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
	case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
	case e1000_82543:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
	case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
		/* No cleanup necessary */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
	case e1000_82547:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
	case e1000_82547_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
		/* Turn on PHY Smart Power Down (if previously enabled) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
					      hw->phy_spd_default);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
		/* Fall Through */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		/* Restore LEDCTL settings */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
		ew32(LEDCTL, hw->ledctl_default);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
 * e1000_led_on - Turns on the software controllable LED
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
s32 e1000_led_on(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
	u32 ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
	e_dbg("e1000_led_on");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
	case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
	case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
	case e1000_82543:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
		/* Set SW Defineable Pin 0 to turn on the LED */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
		ctrl |= E1000_CTRL_SWDPIN0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
		ctrl |= E1000_CTRL_SWDPIO0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
	case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
		if (hw->media_type == e1000_media_type_fiber) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
			/* Set SW Defineable Pin 0 to turn on the LED */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
			ctrl |= E1000_CTRL_SWDPIN0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
			ctrl |= E1000_CTRL_SWDPIO0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
			/* Clear SW Defineable Pin 0 to turn on the LED */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
			ctrl &= ~E1000_CTRL_SWDPIN0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
			ctrl |= E1000_CTRL_SWDPIO0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		if (hw->media_type == e1000_media_type_fiber) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
			/* Clear SW Defineable Pin 0 to turn on the LED */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
			ctrl &= ~E1000_CTRL_SWDPIN0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
			ctrl |= E1000_CTRL_SWDPIO0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
		} else if (hw->media_type == e1000_media_type_copper) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
			ew32(LEDCTL, hw->ledctl_mode2);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
			return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
 * e1000_led_off - Turns off the software controllable LED
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
s32 e1000_led_off(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
	u32 ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
	e_dbg("e1000_led_off");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
	case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
	case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
	case e1000_82543:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		/* Clear SW Defineable Pin 0 to turn off the LED */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
		ctrl &= ~E1000_CTRL_SWDPIN0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
		ctrl |= E1000_CTRL_SWDPIO0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
	case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
		if (hw->media_type == e1000_media_type_fiber) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
			/* Clear SW Defineable Pin 0 to turn off the LED */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
			ctrl &= ~E1000_CTRL_SWDPIN0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
			ctrl |= E1000_CTRL_SWDPIO0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
			/* Set SW Defineable Pin 0 to turn off the LED */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
			ctrl |= E1000_CTRL_SWDPIN0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
			ctrl |= E1000_CTRL_SWDPIO0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		if (hw->media_type == e1000_media_type_fiber) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
			/* Set SW Defineable Pin 0 to turn off the LED */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
			ctrl |= E1000_CTRL_SWDPIN0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
			ctrl |= E1000_CTRL_SWDPIO0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
		} else if (hw->media_type == e1000_media_type_copper) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
			ew32(LEDCTL, hw->ledctl_mode1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
			return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
	ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
 * e1000_clear_hw_cntrs - Clears all hardware statistics counters.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
static void e1000_clear_hw_cntrs(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
	volatile u32 temp __attribute__ ((unused));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	temp = er32(CRCERRS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
	temp = er32(SYMERRS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	temp = er32(MPC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	temp = er32(SCC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	temp = er32(ECOL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	temp = er32(MCC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	temp = er32(LATECOL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
	temp = er32(COLC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
	temp = er32(DC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
	temp = er32(SEC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
	temp = er32(RLEC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
	temp = er32(XONRXC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
	temp = er32(XONTXC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
	temp = er32(XOFFRXC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
	temp = er32(XOFFTXC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	temp = er32(FCRUC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
	temp = er32(PRC64);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
	temp = er32(PRC127);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
	temp = er32(PRC255);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	temp = er32(PRC511);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
	temp = er32(PRC1023);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
	temp = er32(PRC1522);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	temp = er32(GPRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	temp = er32(BPRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
	temp = er32(MPRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
	temp = er32(GPTC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	temp = er32(GORCL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
	temp = er32(GORCH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
	temp = er32(GOTCL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	temp = er32(GOTCH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
	temp = er32(RNBC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
	temp = er32(RUC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	temp = er32(RFC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
	temp = er32(ROC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
	temp = er32(RJC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	temp = er32(TORL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
	temp = er32(TORH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
	temp = er32(TOTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	temp = er32(TOTH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	temp = er32(TPR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	temp = er32(TPT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	temp = er32(PTC64);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
	temp = er32(PTC127);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	temp = er32(PTC255);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	temp = er32(PTC511);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	temp = er32(PTC1023);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
	temp = er32(PTC1522);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
	temp = er32(MPTC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
	temp = er32(BPTC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
	if (hw->mac_type < e1000_82543)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
	temp = er32(ALGNERRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
	temp = er32(RXERRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	temp = er32(TNCRS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	temp = er32(CEXTERR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	temp = er32(TSCTC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	temp = er32(TSCTFC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	if (hw->mac_type <= e1000_82544)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
	temp = er32(MGTPRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	temp = er32(MGTPDC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	temp = er32(MGTPTC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
 * e1000_reset_adaptive - Resets Adaptive IFS to its default state.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
 * Call this after e1000_init_hw. You may override the IFS defaults by setting
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
 * hw->ifs_params_forced to true. However, you must initialize hw->
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
 * current_ifs_val, ifs_min_val, ifs_max_val, ifs_step_size, and ifs_ratio
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
 * before calling this function.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
void e1000_reset_adaptive(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
	e_dbg("e1000_reset_adaptive");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
	if (hw->adaptive_ifs) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
		if (!hw->ifs_params_forced) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
			hw->current_ifs_val = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
			hw->ifs_min_val = IFS_MIN;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
			hw->ifs_max_val = IFS_MAX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
			hw->ifs_step_size = IFS_STEP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
			hw->ifs_ratio = IFS_RATIO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
		hw->in_ifs_mode = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
		ew32(AIT, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
		e_dbg("Not in Adaptive IFS mode!\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
 * e1000_update_adaptive - update adaptive IFS
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
 * @tx_packets: Number of transmits since last callback
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
 * @total_collisions: Number of collisions since last callback
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
 * Called during the callback/watchdog routine to update IFS value based on
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
 * the ratio of transmits to collisions.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
void e1000_update_adaptive(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
	e_dbg("e1000_update_adaptive");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
	if (hw->adaptive_ifs) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
		if ((hw->collision_delta *hw->ifs_ratio) > hw->tx_packet_delta) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
			if (hw->tx_packet_delta > MIN_NUM_XMITS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
				hw->in_ifs_mode = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
				if (hw->current_ifs_val < hw->ifs_max_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
					if (hw->current_ifs_val == 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
						hw->current_ifs_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
						    hw->ifs_min_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
					else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
						hw->current_ifs_val +=
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
						    hw->ifs_step_size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
					ew32(AIT, hw->current_ifs_val);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
				}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
			if (hw->in_ifs_mode
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
			    && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
				hw->current_ifs_val = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
				hw->in_ifs_mode = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
				ew32(AIT, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
		e_dbg("Not in Adaptive IFS mode!\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
 * e1000_tbi_adjust_stats
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
 * @frame_len: The length of the frame in question
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
 * @mac_addr: The Ethernet destination address of the frame in question
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
 * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
			    u32 frame_len, u8 *mac_addr)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
	u64 carry_bit;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
	/* First adjust the frame length. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
	frame_len--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	/* We need to adjust the statistics counters, since the hardware
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
	 * counters overcount this packet as a CRC error and undercount
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
	 * the packet as a good packet
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
	/* This packet should not be counted as a CRC error.    */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
	stats->crcerrs--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
	/* This packet does count as a Good Packet Received.    */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	stats->gprc++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	/* Adjust the Good Octets received counters             */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	carry_bit = 0x80000000 & stats->gorcl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	stats->gorcl += frame_len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	/* If the high bit of Gorcl (the low 32 bits of the Good Octets
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	 * Received Count) was one before the addition,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	 * AND it is zero after, then we lost the carry out,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	 * need to add one to Gorch (Good Octets Received Count High).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	 * This could be simplified if all environments supported
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
	 * 64-bit integers.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
		stats->gorch++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
	/* Is this a broadcast or multicast?  Check broadcast first,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
	 * since the test for a multicast frame will test positive on
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
	 * a broadcast frame.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
	if ((mac_addr[0] == (u8) 0xff) && (mac_addr[1] == (u8) 0xff))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
		/* Broadcast packet */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
		stats->bprc++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	else if (*mac_addr & 0x01)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
		/* Multicast packet */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
		stats->mprc++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	if (frame_len == hw->max_frame_size) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
		/* In this case, the hardware has overcounted the number of
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
		 * oversize frames.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
		if (stats->roc > 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
			stats->roc--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
	/* Adjust the bin counters when the extra byte put the frame in the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	 * wrong bin. Remember that the frame_len was adjusted above.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	if (frame_len == 64) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
		stats->prc64++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
		stats->prc127--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	} else if (frame_len == 127) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
		stats->prc127++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
		stats->prc255--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	} else if (frame_len == 255) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
		stats->prc255++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
		stats->prc511--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	} else if (frame_len == 511) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
		stats->prc511++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
		stats->prc1023--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	} else if (frame_len == 1023) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
		stats->prc1023++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
		stats->prc1522--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
	} else if (frame_len == 1522) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
		stats->prc1522++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
 * e1000_get_bus_info
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
 * Gets the current PCI bus type, speed, and width of the hardware
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
void e1000_get_bus_info(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	u32 status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
	case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
		hw->bus_type = e1000_bus_type_pci;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
		hw->bus_speed = e1000_bus_speed_unknown;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
		hw->bus_width = e1000_bus_width_unknown;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
		status = er32(STATUS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
		hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
		    e1000_bus_type_pcix : e1000_bus_type_pci;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
		if (hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
			hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
			    e1000_bus_speed_66 : e1000_bus_speed_120;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
		} else if (hw->bus_type == e1000_bus_type_pci) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
			hw->bus_speed = (status & E1000_STATUS_PCI66) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
			    e1000_bus_speed_66 : e1000_bus_speed_33;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
			switch (status & E1000_STATUS_PCIX_SPEED) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
			case E1000_STATUS_PCIX_SPEED_66:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
				hw->bus_speed = e1000_bus_speed_66;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
			case E1000_STATUS_PCIX_SPEED_100:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
				hw->bus_speed = e1000_bus_speed_100;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
			case E1000_STATUS_PCIX_SPEED_133:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
				hw->bus_speed = e1000_bus_speed_133;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
			default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
				hw->bus_speed = e1000_bus_speed_reserved;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
		hw->bus_width = (status & E1000_STATUS_BUS64) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
		    e1000_bus_width_64 : e1000_bus_width_32;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
 * e1000_write_reg_io
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
 * @offset: offset to write to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
 * @value: value to write
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
 * Writes a value to one of the devices registers using port I/O (as opposed to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
 * memory mapped I/O). Only 82544 and newer devices support port I/O.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
	unsigned long io_addr = hw->io_base;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
	unsigned long io_data = hw->io_base + 4;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
	e1000_io_write(hw, io_addr, offset);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
	e1000_io_write(hw, io_data, value);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
 * e1000_get_cable_length - Estimates the cable length.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
 * @min_length: The estimated minimum length
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
 * @max_length: The estimated maximum length
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
 * returns: - E1000_ERR_XXX
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
 *            E1000_SUCCESS
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
 * This function always returns a ranged length (minimum & maximum).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
 * So for M88 phy's, this function interprets the one value returned from the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
 * register to the minimum and maximum range.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
 * For IGP phy's, the function calculates the range by the AGC registers.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
				  u16 *max_length)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
	u16 agc_value = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
	u16 i, phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
	u16 cable_length;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	e_dbg("e1000_get_cable_length");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
	*min_length = *max_length = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
	/* Use old method for Phy older than IGP */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
	if (hw->phy_type == e1000_phy_m88) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
					     &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
		cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
		    M88E1000_PSSR_CABLE_LENGTH_SHIFT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
		/* Convert the enum value to ranged values */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
		switch (cable_length) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
		case e1000_cable_length_50:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
			*min_length = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
			*max_length = e1000_igp_cable_length_50;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
		case e1000_cable_length_50_80:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
			*min_length = e1000_igp_cable_length_50;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
			*max_length = e1000_igp_cable_length_80;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
		case e1000_cable_length_80_110:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
			*min_length = e1000_igp_cable_length_80;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
			*max_length = e1000_igp_cable_length_110;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
		case e1000_cable_length_110_140:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
			*min_length = e1000_igp_cable_length_110;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
			*max_length = e1000_igp_cable_length_140;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
		case e1000_cable_length_140:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
			*min_length = e1000_igp_cable_length_140;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
			*max_length = e1000_igp_cable_length_170;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
		default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
			return -E1000_ERR_PHY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
	} else if (hw->phy_type == e1000_phy_igp) {	/* For IGP PHY */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
		u16 cur_agc_value;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
		u16 min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
		u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
		    { IGP01E1000_PHY_AGC_A,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
			IGP01E1000_PHY_AGC_B,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
			IGP01E1000_PHY_AGC_C,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
			IGP01E1000_PHY_AGC_D
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
		};
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
		/* Read the AGC registers for all channels */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
		for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
			    e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
			cur_agc_value = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
			/* Value bound check. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
			if ((cur_agc_value >=
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
			     IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
			    || (cur_agc_value == 0))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
				return -E1000_ERR_PHY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
			agc_value += cur_agc_value;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
			/* Update minimal AGC value. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
			if (min_agc_value > cur_agc_value)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
				min_agc_value = cur_agc_value;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
		/* Remove the minimal AGC result for length < 50m */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
		if (agc_value <
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
		    IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
			agc_value -= min_agc_value;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
			/* Get the average length of the remaining 3 channels */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
			agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
			/* Get the average length of all the 4 channels. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
			agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
		/* Set the range of the calculated length. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
		*min_length = ((e1000_igp_cable_length_table[agc_value] -
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
				IGP01E1000_AGC_RANGE) > 0) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
		    (e1000_igp_cable_length_table[agc_value] -
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
		     IGP01E1000_AGC_RANGE) : 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
		*max_length = e1000_igp_cable_length_table[agc_value] +
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
		    IGP01E1000_AGC_RANGE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
 * e1000_check_polarity - Check the cable polarity
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
 * @polarity: output parameter : 0 - Polarity is not reversed
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
 *                               1 - Polarity is reversed.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
 * returns: - E1000_ERR_XXX
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
 *            E1000_SUCCESS
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
 * For phy's older than IGP, this function simply reads the polarity bit in the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
 * Phy Status register.  For IGP phy's, this bit is valid only if link speed is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
 * 10 Mbps.  If the link speed is 100 Mbps there is no polarity so this bit will
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
 * return 0.  If the link speed is 1000 Mbps the polarity status is in the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
 * IGP01E1000_PHY_PCS_INIT_REG.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
static s32 e1000_check_polarity(struct e1000_hw *hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
				e1000_rev_polarity *polarity)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
	e_dbg("e1000_check_polarity");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
	if (hw->phy_type == e1000_phy_m88) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
		/* return the Polarity bit in the Status register. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
					     &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
		*polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
			     M88E1000_PSSR_REV_POLARITY_SHIFT) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
		    e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
	} else if (hw->phy_type == e1000_phy_igp) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
		/* Read the Status register to check the speed */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
					     &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
		/* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
		 * find the polarity status */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
		if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
		    IGP01E1000_PSSR_SPEED_1000MBPS) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
			/* Read the GIG initialization PCS register (0x00B4) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
					       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
			/* Check the polarity bits */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
			*polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
			    e1000_rev_polarity_reversed :
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
			    e1000_rev_polarity_normal;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
			/* For 10 Mbps, read the polarity bit in the status register. (for
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
			 * 100 Mbps this bit is always 0) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
			*polarity =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
			    (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
			    e1000_rev_polarity_reversed :
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
			    e1000_rev_polarity_normal;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
 * e1000_check_downshift - Check if Downshift occurred
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
 * @downshift: output parameter : 0 - No Downshift occurred.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
 *                                1 - Downshift occurred.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
 * returns: - E1000_ERR_XXX
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
 *            E1000_SUCCESS
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
 * For phy's older than IGP, this function reads the Downshift bit in the Phy
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
 * Specific Status register.  For IGP phy's, it reads the Downgrade bit in the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
 * Link Health register.  In IGP this bit is latched high, so the driver must
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
 * read it immediately after link is established.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
static s32 e1000_check_downshift(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
	e_dbg("e1000_check_downshift");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
	if (hw->phy_type == e1000_phy_igp) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
					     &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
		hw->speed_downgraded =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
		    (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
	} else if (hw->phy_type == e1000_phy_m88) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
					     &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
		hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
		    M88E1000_PSSR_DOWNSHIFT_SHIFT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
 * e1000_config_dsp_after_link_change
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
 * @link_up: was link up at the time this was called
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
 *            E1000_SUCCESS at any other case.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
 * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
 * gigabit link is achieved to improve link quality.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw, bool link_up)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	u16 phy_data, phy_saved_data, speed, duplex, i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
	u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
	    { IGP01E1000_PHY_AGC_PARAM_A,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
		IGP01E1000_PHY_AGC_PARAM_B,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
		IGP01E1000_PHY_AGC_PARAM_C,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
		IGP01E1000_PHY_AGC_PARAM_D
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
	};
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
	u16 min_length, max_length;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
	e_dbg("e1000_config_dsp_after_link_change");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
	if (hw->phy_type != e1000_phy_igp)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
	if (link_up) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
		ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
			e_dbg("Error getting link speed and duplex\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
		if (speed == SPEED_1000) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
			    e1000_get_cable_length(hw, &min_length,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
						   &max_length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
			if ((hw->dsp_config_state == e1000_dsp_config_enabled)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
			    && min_length >= e1000_igp_cable_length_50) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
				for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
					ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
					    e1000_read_phy_reg(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
							       dsp_reg_array[i],
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
							       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
					if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
						return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
					phy_data &=
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
					    ~IGP01E1000_PHY_EDAC_MU_INDEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
					ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
					    e1000_write_phy_reg(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
								dsp_reg_array
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
								[i], phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
					if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
						return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
				}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
				hw->dsp_config_state =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
				    e1000_dsp_config_activated;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
			if ((hw->ffe_config_state == e1000_ffe_config_enabled)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
			    && (min_length < e1000_igp_cable_length_50)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
				u16 ffe_idle_err_timeout =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
				    FFE_IDLE_ERR_COUNT_TIMEOUT_20;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
				u32 idle_errs = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
				/* clear previous idle error counts */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
				ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
				    e1000_read_phy_reg(hw, PHY_1000T_STATUS,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
						       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
				if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
					return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
				for (i = 0; i < ffe_idle_err_timeout; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
					udelay(1000);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
					ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
					    e1000_read_phy_reg(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
							       PHY_1000T_STATUS,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
							       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
					if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
						return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
					idle_errs +=
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
					    (phy_data &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
					     SR_1000T_IDLE_ERROR_CNT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
					if (idle_errs >
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
					    SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
					{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
						hw->ffe_config_state =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
						    e1000_ffe_config_active;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
						ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
						    e1000_write_phy_reg(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
									IGP01E1000_PHY_DSP_FFE,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
									IGP01E1000_PHY_DSP_FFE_CM_CP);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
						if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
							return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
						break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
					}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
					if (idle_errs)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
						ffe_idle_err_timeout =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
						    FFE_IDLE_ERR_COUNT_TIMEOUT_100;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
				}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
		if (hw->dsp_config_state == e1000_dsp_config_activated) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
			/* Save off the current value of register 0x2F5B to be restored at
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
			 * the end of the routines. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
			    e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
			/* Disable the PHY transmitter */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
			ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
			mdelay(20);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
			ret_val = e1000_write_phy_reg(hw, 0x0000,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
						      IGP01E1000_IEEE_FORCE_GIGA);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
			for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
				ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
				    e1000_read_phy_reg(hw, dsp_reg_array[i],
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
						       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
				if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
					return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
				phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
				phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
				ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
				    e1000_write_phy_reg(hw, dsp_reg_array[i],
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
							phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
				if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
					return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
			ret_val = e1000_write_phy_reg(hw, 0x0000,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
						      IGP01E1000_IEEE_RESTART_AUTONEG);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
			mdelay(20);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
			/* Now enable the transmitter */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
			    e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
			hw->dsp_config_state = e1000_dsp_config_enabled;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
		if (hw->ffe_config_state == e1000_ffe_config_active) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
			/* Save off the current value of register 0x2F5B to be restored at
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
			 * the end of the routines. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
			    e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
			/* Disable the PHY transmitter */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
			ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
			mdelay(20);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
			ret_val = e1000_write_phy_reg(hw, 0x0000,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
						      IGP01E1000_IEEE_FORCE_GIGA);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
						IGP01E1000_PHY_DSP_FFE_DEFAULT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
			ret_val = e1000_write_phy_reg(hw, 0x0000,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
						      IGP01E1000_IEEE_RESTART_AUTONEG);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
			mdelay(20);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
			/* Now enable the transmitter */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
			    e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
			hw->ffe_config_state = e1000_ffe_config_enabled;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
 * e1000_set_phy_mode - Set PHY to class A mode
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
 * Assumes the following operations will follow to enable the new class mode.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
 *  1. Do a PHY soft reset
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
 *  2. Restart auto-negotiation or force link.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
static s32 e1000_set_phy_mode(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
	u16 eeprom_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
	e_dbg("e1000_set_phy_mode");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
	if ((hw->mac_type == e1000_82545_rev_3) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
	    (hw->media_type == e1000_media_type_copper)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
		    e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
				      &eeprom_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
		if (ret_val) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
		if ((eeprom_data != EEPROM_RESERVED_WORD) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
		    (eeprom_data & EEPROM_PHY_CLASS_A)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
			    e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
						0x000B);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
			    e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
						0x8104);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
			hw->phy_reset_disable = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
 * e1000_set_d3_lplu_state - set d3 link power state
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
 * @active: true to enable lplu false to disable lplu.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
 * This function sets the lplu state according to the active flag.  When
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
 * activating lplu this function also disables smart speed and vise versa.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
 * lplu will not be activated unless the device autonegotiation advertisement
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
 * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
 *            E1000_SUCCESS at any other case.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
	e_dbg("e1000_set_d3_lplu_state");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
	if (hw->phy_type != e1000_phy_igp)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
	/* During driver activity LPLU should not be used or it will attain link
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
	 * from the lowest speeds starting from 10Mbps. The capability is used for
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
	 * Dx transitions and states */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
	if (hw->mac_type == e1000_82541_rev_2
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
	    || hw->mac_type == e1000_82547_rev_2) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
		    e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
	if (!active) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
		if (hw->mac_type == e1000_82541_rev_2 ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
		    hw->mac_type == e1000_82547_rev_2) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
			phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
			    e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
						phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
		 * Dx states where the power conservation is most important.  During
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
		 * driver activity we should enable SmartSpeed, so performance is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
		 * maintained. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
		if (hw->smart_speed == e1000_smart_speed_on) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
					       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
			phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
						phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
		} else if (hw->smart_speed == e1000_smart_speed_off) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
					       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
						phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
	} else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
		   || (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
		   || (hw->autoneg_advertised ==
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
		       AUTONEG_ADVERTISE_10_100_ALL)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
		if (hw->mac_type == e1000_82541_rev_2 ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
		    hw->mac_type == e1000_82547_rev_2) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
			phy_data |= IGP01E1000_GMII_FLEX_SPD;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
			ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
			    e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
						phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
			if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
				return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
		/* When LPLU is enabled we should disable SmartSpeed */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
		    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
				       &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
		phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
		ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
		    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
					phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
 * e1000_set_vco_speed
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
 * Change VCO speed register to improve Bit Error Rate performance of SERDES.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
static s32 e1000_set_vco_speed(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
	u16 default_page = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
	u16 phy_data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
	e_dbg("e1000_set_vco_speed");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
	case e1000_82545_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
	case e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
		return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
	/* Set PHY register 30, page 5, bit 8 to 0 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
	ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
	    e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
	phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
	/* Set PHY register 30, page 4, bit 11 to 1 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
	phy_data |= M88E1000_PHY_VCO_REG_BIT11;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
	ret_val =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
	    e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
 * e1000_enable_mng_pass_thru - check for bmc pass through
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
 * Verifies the hardware needs to allow ARPs to be processed by the host
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
 * returns: - true/false
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
u32 e1000_enable_mng_pass_thru(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
	u32 manc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
	if (hw->asf_firmware_present) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
		manc = er32(MANC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
		if (!(manc & E1000_MANC_RCV_TCO_EN) ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
		    !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
			return false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
		if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
			return true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
	return false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
	s32 ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
	u16 mii_status_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
	u16 i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
	/* Polarity reversal workaround for forced 10F/10H links. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
	/* Disable the transmitter on the PHY */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
	/* This loop will early-out if the NO link condition has been met. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
	for (i = PHY_FORCE_TIME; i > 0; i--) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
		/* Read the MII Status Register and wait for Link Status bit
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
		 * to be clear.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
		if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
		mdelay(100);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
	/* Recommended delay time after link has been lost */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
	mdelay(1000);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
	/* Now we will re-enable th transmitter on the PHY */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
	mdelay(50);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
	mdelay(50);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
	mdelay(50);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
		return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
	/* This loop will early-out if the link condition has been met. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
	for (i = PHY_FORCE_TIME; i > 0; i--) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
		/* Read the MII Status Register and wait for Link Status bit
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
		 * to be set.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
		if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
			return ret_val;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
		if (mii_status_reg & MII_SR_LINK_STATUS)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
		mdelay(100);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
 * e1000_get_auto_rd_done
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
 * Check for EEPROM Auto Read bit done.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
 * returns: - E1000_ERR_RESET if fail to reset MAC
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
 *            E1000_SUCCESS at any other case.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
	e_dbg("e1000_get_auto_rd_done");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
	msleep(5);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
 * e1000_get_phy_cfg_done
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
 * @hw: Struct containing variables accessed by shared code
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
 * Checks if the PHY configuration is done
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
 * returns: - E1000_ERR_RESET if fail to reset MAC
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
 *            E1000_SUCCESS at any other case.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
	e_dbg("e1000_get_phy_cfg_done");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
	mdelay(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
}