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

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2494
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
/* e1000_hw.c
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
 * Shared functions for accessing and configuring the MAC
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include "e1000.h"
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
static s32 e1000_check_downshift(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static s32 e1000_check_polarity(struct e1000_hw *hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
				e1000_rev_polarity *polarity);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
static void e1000_clear_vfta(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
					      bool link_up);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
static s32 e1000_detect_gig_phy(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
				  u16 *max_length);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
static s32 e1000_id_led_init(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
static void e1000_init_rx_addrs(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
				  struct e1000_phy_info *phy_info);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
				  struct e1000_phy_info *phy_info);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
static s32 e1000_wait_autoneg(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
static s32 e1000_set_phy_type(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
static void e1000_phy_init_script(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
static s32 e1000_setup_copper_link(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
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);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
				  u16 words, u16 *data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
					u16 words, u16 *data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
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);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
				  u16 phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
				 u16 *phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
static s32 e1000_acquire_eeprom(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
static void e1000_release_eeprom(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
static void e1000_standby_eeprom(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
static s32 e1000_set_vco_speed(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
static s32 e1000_set_phy_mode(struct e1000_hw *hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
				u16 *data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
				 u16 *data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
/* IGP cable length table */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
static const
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
u16 e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = {
d1bd39013a32 Added e1000 driver for kernel 3.4.
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,
d1bd39013a32 Added e1000 driver for kernel 3.4.
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,
d1bd39013a32 Added e1000 driver for kernel 3.4.
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,
d1bd39013a32 Added e1000 driver for kernel 3.4.
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,
d1bd39013a32 Added e1000 driver for kernel 3.4.
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,
d1bd39013a32 Added e1000 driver for kernel 3.4.
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,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	    100,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	    110, 110,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	    120, 120
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
};
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static DEFINE_SPINLOCK(e1000_eeprom_lock);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
 * e1000_set_phy_type - Set the phy type member in the hw struct.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static s32 e1000_set_phy_type(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	e_dbg("e1000_set_phy_type");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	if (hw->mac_type == e1000_undefined)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
		return -E1000_ERR_PHY_TYPE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	switch (hw->phy_id) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	case M88E1000_E_PHY_ID:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	case M88E1000_I_PHY_ID:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	case M88E1011_I_PHY_ID:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	case M88E1111_I_PHY_ID:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	case M88E1118_E_PHY_ID:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
		hw->phy_type = e1000_phy_m88;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	case IGP01E1000_I_PHY_ID:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
		if (hw->mac_type == e1000_82541 ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
		    hw->mac_type == e1000_82541_rev_2 ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
		    hw->mac_type == e1000_82547 ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
		    hw->mac_type == e1000_82547_rev_2)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
			hw->phy_type = e1000_phy_igp;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
	case RTL8211B_PHY_ID:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
		hw->phy_type = e1000_phy_8211;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
	case RTL8201N_PHY_ID:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
		hw->phy_type = e1000_phy_8201;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
		/* Should never have loaded on this device */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
		hw->phy_type = e1000_phy_undefined;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
		return -E1000_ERR_PHY_TYPE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
 * e1000_phy_init_script - IGP phy init script - initializes the GbE PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_phy_init_script(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
	u32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
	u16 phy_saved_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
	e_dbg("e1000_phy_init_script");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
	if (hw->phy_init_script) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
		msleep(20);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
		/* Save off the current value of register 0x2F5B to be restored at
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
		 * the end of this routine. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
		ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
		/* Disabled the PHY transmitter */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
		msleep(20);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
		e1000_write_phy_reg(hw, 0x0000, 0x0140);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
		msleep(5);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
		switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
		case e1000_82541:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
		case e1000_82547:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
			e1000_write_phy_reg(hw, 0x1F95, 0x0001);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
			e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
			e1000_write_phy_reg(hw, 0x1F79, 0x0018);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
			e1000_write_phy_reg(hw, 0x1F30, 0x1600);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
			e1000_write_phy_reg(hw, 0x1F31, 0x0014);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
			e1000_write_phy_reg(hw, 0x1F32, 0x161C);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
			e1000_write_phy_reg(hw, 0x1F94, 0x0003);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
			e1000_write_phy_reg(hw, 0x1F96, 0x003F);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
			e1000_write_phy_reg(hw, 0x2010, 0x0008);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
		case e1000_82541_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
		case e1000_82547_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
			e1000_write_phy_reg(hw, 0x1F73, 0x0099);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
		default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		e1000_write_phy_reg(hw, 0x0000, 0x3300);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
		msleep(20);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
		/* Now enable the transmitter */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
		e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
		if (hw->mac_type == e1000_82547) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
			u16 fused, fine, coarse;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
			/* Move to analog registers page */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
			e1000_read_phy_reg(hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
					   IGP01E1000_ANALOG_SPARE_FUSE_STATUS,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
					   &fused);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
			if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
				e1000_read_phy_reg(hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
						   IGP01E1000_ANALOG_FUSE_STATUS,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
						   &fused);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
				fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
				coarse =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
				    fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
				if (coarse >
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
				    IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
					coarse -=
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
					    IGP01E1000_ANALOG_FUSE_COARSE_10;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
					fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
				} else if (coarse ==
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
					   IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
					fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
				fused =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
				    (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
				    (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
				    (coarse &
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
				     IGP01E1000_ANALOG_FUSE_COARSE_MASK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
				e1000_write_phy_reg(hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
						    IGP01E1000_ANALOG_FUSE_CONTROL,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
						    fused);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
				e1000_write_phy_reg(hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
						    IGP01E1000_ANALOG_FUSE_BYPASS,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
						    IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
 * e1000_set_mac_type - Set the mac type member in the hw struct.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
s32 e1000_set_mac_type(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	e_dbg("e1000_set_mac_type");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	switch (hw->device_id) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	case E1000_DEV_ID_82542:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
		switch (hw->revision_id) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
		case E1000_82542_2_0_REV_ID:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
			hw->mac_type = e1000_82542_rev2_0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
		case E1000_82542_2_1_REV_ID:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
			hw->mac_type = e1000_82542_rev2_1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
		default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
			/* Invalid 82542 revision ID */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
			return -E1000_ERR_MAC_TYPE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	case E1000_DEV_ID_82543GC_FIBER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	case E1000_DEV_ID_82543GC_COPPER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
		hw->mac_type = e1000_82543;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	case E1000_DEV_ID_82544EI_COPPER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	case E1000_DEV_ID_82544EI_FIBER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	case E1000_DEV_ID_82544GC_COPPER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	case E1000_DEV_ID_82544GC_LOM:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		hw->mac_type = e1000_82544;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	case E1000_DEV_ID_82540EM:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	case E1000_DEV_ID_82540EM_LOM:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	case E1000_DEV_ID_82540EP:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	case E1000_DEV_ID_82540EP_LOM:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	case E1000_DEV_ID_82540EP_LP:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
		hw->mac_type = e1000_82540;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	case E1000_DEV_ID_82545EM_COPPER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	case E1000_DEV_ID_82545EM_FIBER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		hw->mac_type = e1000_82545;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	case E1000_DEV_ID_82545GM_COPPER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	case E1000_DEV_ID_82545GM_FIBER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	case E1000_DEV_ID_82545GM_SERDES:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
		hw->mac_type = e1000_82545_rev_3;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	case E1000_DEV_ID_82546EB_COPPER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	case E1000_DEV_ID_82546EB_FIBER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
		hw->mac_type = e1000_82546;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	case E1000_DEV_ID_82546GB_COPPER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	case E1000_DEV_ID_82546GB_FIBER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	case E1000_DEV_ID_82546GB_SERDES:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	case E1000_DEV_ID_82546GB_PCIE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	case E1000_DEV_ID_82546GB_QUAD_COPPER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
		hw->mac_type = e1000_82546_rev_3;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	case E1000_DEV_ID_82541EI:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	case E1000_DEV_ID_82541EI_MOBILE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	case E1000_DEV_ID_82541ER_LOM:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		hw->mac_type = e1000_82541;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	case E1000_DEV_ID_82541ER:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	case E1000_DEV_ID_82541GI:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	case E1000_DEV_ID_82541GI_LF:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	case E1000_DEV_ID_82541GI_MOBILE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
		hw->mac_type = e1000_82541_rev_2;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	case E1000_DEV_ID_82547EI:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	case E1000_DEV_ID_82547EI_MOBILE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
		hw->mac_type = e1000_82547;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	case E1000_DEV_ID_82547GI:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		hw->mac_type = e1000_82547_rev_2;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	case E1000_DEV_ID_INTEL_CE4100_GBE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
		hw->mac_type = e1000_ce4100;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		/* Should never have loaded on this device */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		return -E1000_ERR_MAC_TYPE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	case e1000_82541:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	case e1000_82547:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	case e1000_82541_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	case e1000_82547_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		hw->asf_firmware_present = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	/* The 82543 chip does not count tx_carrier_errors properly in
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
	 * FD mode
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	if (hw->mac_type == e1000_82543)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		hw->bad_tx_carr_stats_fd = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
	if (hw->mac_type > e1000_82544)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
		hw->has_smbus = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
 * e1000_set_media_type - Set media type and TBI compatibility.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
void e1000_set_media_type(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	u32 status;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	e_dbg("e1000_set_media_type");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	if (hw->mac_type != e1000_82543) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
		/* tbi_compatibility is only valid on 82543 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		hw->tbi_compatibility_en = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	switch (hw->device_id) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
	case E1000_DEV_ID_82545GM_SERDES:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	case E1000_DEV_ID_82546GB_SERDES:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		hw->media_type = e1000_media_type_internal_serdes;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
		switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
		case e1000_82542_rev2_0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
		case e1000_82542_rev2_1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
			hw->media_type = e1000_media_type_fiber;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
		case e1000_ce4100:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
			hw->media_type = e1000_media_type_copper;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
		default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
			status = er32(STATUS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
			if (status & E1000_STATUS_TBIMODE) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
				hw->media_type = e1000_media_type_fiber;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
				/* tbi_compatibility not valid on fiber */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
				hw->tbi_compatibility_en = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
			} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
				hw->media_type = e1000_media_type_copper;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
 * e1000_reset_hw: reset the hardware completely
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
 * Reset the transmit and receive units; mask and clear all interrupts.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
s32 e1000_reset_hw(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	u32 ctrl_ext;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	u32 icr;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	u32 manc;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	u32 led_ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	e_dbg("e1000_reset_hw");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	/* For 82542 (rev 2.0), disable MWI before issuing a device reset */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	if (hw->mac_type == e1000_82542_rev2_0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
		e_dbg("Disabling MWI on 82542 rev 2.0\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
		e1000_pci_clear_mwi(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	/* Clear interrupt mask to stop board from generating interrupts */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	e_dbg("Masking off all interrupts\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	ew32(IMC, 0xffffffff);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	/* Disable the Transmit and Receive units.  Then delay to allow
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	 * any pending transactions to complete before we hit the MAC with
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	 * the global reset.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	ew32(RCTL, 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	ew32(TCTL, E1000_TCTL_PSP);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
	/* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
	hw->tbi_compatibility_on = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	/* Delay to allow any outstanding PCI transactions to complete before
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
	 * resetting the device
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	msleep(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	/* Must reset the PHY before resetting the MAC */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
		ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
		msleep(5);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	/* Issue a global reset to the MAC.  This will reset the chip's
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	 * transmit, receive, DMA, and link units.  It will not effect
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
	 * the current PCI configuration.  The global reset bit is self-
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	 * clearing, and should clear within a microsecond.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	e_dbg("Issuing a global reset to MAC\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
	case e1000_82544:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	case e1000_82540:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	case e1000_82545:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	case e1000_82546:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
	case e1000_82541:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	case e1000_82541_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
		/* These controllers can't ack the 64-bit write when issuing the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
		 * reset, so use IO-mapping as a workaround to issue the reset */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
		E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	case e1000_82545_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	case e1000_82546_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		/* Reset is performed on a shadow of the control register */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		ew32(CTRL_DUP, (ctrl | E1000_CTRL_RST));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	case e1000_ce4100:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
		ew32(CTRL, (ctrl | E1000_CTRL_RST));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	/* After MAC reset, force reload of EEPROM to restore power-on settings to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	 * device.  Later controllers reload the EEPROM automatically, so just wait
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	 * for reload to complete.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	case e1000_82542_rev2_0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	case e1000_82542_rev2_1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	case e1000_82543:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	case e1000_82544:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		/* Wait for reset to complete */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
		udelay(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
		ctrl_ext = er32(CTRL_EXT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		ctrl_ext |= E1000_CTRL_EXT_EE_RST;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		ew32(CTRL_EXT, ctrl_ext);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
		/* Wait for EEPROM reload */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		msleep(2);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	case e1000_82541:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	case e1000_82541_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	case e1000_82547:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	case e1000_82547_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		/* Wait for EEPROM reload */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		msleep(20);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
		/* Auto read done will delay 5ms or poll based on mac type */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
		ret_val = e1000_get_auto_rd_done(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	/* Disable HW ARPs on ASF enabled adapters */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	if (hw->mac_type >= e1000_82540) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
		manc = er32(MANC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
		manc &= ~(E1000_MANC_ARP_EN);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
		ew32(MANC, manc);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
		e1000_phy_init_script(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
		/* Configure activity LED after PHY reset */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		led_ctrl = er32(LEDCTL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
		ew32(LEDCTL, led_ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	/* Clear interrupt mask to stop board from generating interrupts */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	e_dbg("Masking off all interrupts\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	ew32(IMC, 0xffffffff);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	/* Clear any pending interrupt events. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	icr = er32(ICR);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	/* If MWI was previously enabled, reenable it. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	if (hw->mac_type == e1000_82542_rev2_0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
		if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
			e1000_pci_set_mwi(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
 * e1000_init_hw: Performs basic configuration of the adapter.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
 * Assumes that the controller has previously been reset and is in a
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
 * post-reset uninitialized state. Initializes the receive address registers,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
 * multicast table, and VLAN filter table. Calls routines to setup link
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
 * configuration and flow control settings. Clears all on-chip counters. Leaves
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
 * the transmit and receive units disabled and uninitialized.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
s32 e1000_init_hw(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	u32 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
	u32 mta_size;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	u32 ctrl_ext;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	e_dbg("e1000_init_hw");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	/* Initialize Identification LED */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	ret_val = e1000_id_led_init(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
		e_dbg("Error Initializing Identification LED\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	/* Set the media type and TBI compatibility */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	e1000_set_media_type(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	/* Disabling VLAN filtering. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	e_dbg("Initializing the IEEE VLAN\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	if (hw->mac_type < e1000_82545_rev_3)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
		ew32(VET, 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	e1000_clear_vfta(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	if (hw->mac_type == e1000_82542_rev2_0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		e_dbg("Disabling MWI on 82542 rev 2.0\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		e1000_pci_clear_mwi(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		ew32(RCTL, E1000_RCTL_RST);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
		msleep(5);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	/* Setup the receive address. This involves initializing all of the Receive
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	 * Address Registers (RARs 0 - 15).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	e1000_init_rx_addrs(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	if (hw->mac_type == e1000_82542_rev2_0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		ew32(RCTL, 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		msleep(1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
		if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
			e1000_pci_set_mwi(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	/* Zero out the Multicast HASH table */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	e_dbg("Zeroing the MTA\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	mta_size = E1000_MC_TBL_SIZE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	for (i = 0; i < mta_size; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
		/* use write flush to prevent Memory Write Block (MWB) from
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		 * occurring when accessing our register space */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	/* Set the PCI priority bit correctly in the CTRL register.  This
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	 * determines if the adapter gives priority to receives, or if it
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	 * gives equal priority to transmits and receives.  Valid only on
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	 * 82542 and 82543 silicon.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
	if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
		ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
		ew32(CTRL, ctrl | E1000_CTRL_PRIOR);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	case e1000_82545_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	case e1000_82546_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		/* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		if (hw->bus_type == e1000_bus_type_pcix
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		    && e1000_pcix_get_mmrbc(hw) > 2048)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
			e1000_pcix_set_mmrbc(hw, 2048);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	/* Call a subroutine to configure the link and setup flow control. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	ret_val = e1000_setup_link(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	/* Set the transmit descriptor write-back policy */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	if (hw->mac_type > e1000_82544) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
		ctrl = er32(TXDCTL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
		ctrl =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		    (ctrl & ~E1000_TXDCTL_WTHRESH) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		    E1000_TXDCTL_FULL_TX_DESC_WB;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		ew32(TXDCTL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	/* Clear all of the statistics registers (clear on read).  It is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	 * important that we do this after we have tried to establish link
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	 * because the symbol error count will increment wildly if there
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	 * is no link.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	e1000_clear_hw_cntrs(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
	if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	    hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
		ctrl_ext = er32(CTRL_EXT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
		/* Relaxed ordering must be disabled to avoid a parity
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
		 * error crash in a PCI slot. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
		ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
		ew32(CTRL_EXT, ctrl_ext);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
 * e1000_adjust_serdes_amplitude - Adjust SERDES output amplitude based on EEPROM setting.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
 * @hw: Struct containing variables accessed by shared code.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	u16 eeprom_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	e_dbg("e1000_adjust_serdes_amplitude");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
	if (hw->media_type != e1000_media_type_internal_serdes)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	case e1000_82545_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
	case e1000_82546_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	                            &eeprom_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	if (eeprom_data != EEPROM_RESERVED_WORD) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
		/* Adjust SERDES output amplitude only. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
		    e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
 * e1000_setup_link - Configures flow control and link settings.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
 * Determines which flow control settings to use. Calls the appropriate media-
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
 * specific link configuration function. Configures the flow control settings.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
 * Assuming the adapter has a valid link partner, a valid link should be
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
 * established. Assumes the hardware has previously been reset and the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
 * transmitter and receiver are not enabled.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
s32 e1000_setup_link(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	u32 ctrl_ext;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	u16 eeprom_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	e_dbg("e1000_setup_link");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	/* Read and store word 0x0F of the EEPROM. This word contains bits
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	 * that determine the hardware's default PAUSE (flow control) mode,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	 * a bit that determines whether the HW defaults to enabling or
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	 * disabling auto-negotiation, and the direction of the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	 * SW defined pins. If there is no SW over-ride of the flow
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	 * control setting, then the variable hw->fc will
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	 * be initialized based on a value in the EEPROM.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	if (hw->fc == E1000_FC_DEFAULT) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
		ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
					    1, &eeprom_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
			e_dbg("EEPROM Read Error\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
			return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
		if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
			hw->fc = E1000_FC_NONE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
		else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
			 EEPROM_WORD0F_ASM_DIR)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
			hw->fc = E1000_FC_TX_PAUSE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		else
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
			hw->fc = E1000_FC_FULL;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	/* We want to save off the original Flow Control configuration just
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	 * in case we get disconnected and then reconnected into a different
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	 * hub or switch with different Flow Control capabilities.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	if (hw->mac_type == e1000_82542_rev2_0)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
		hw->fc &= (~E1000_FC_TX_PAUSE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
		hw->fc &= (~E1000_FC_RX_PAUSE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	hw->original_fc = hw->fc;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	/* Take the 4 bits from EEPROM word 0x0F that determine the initial
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	 * polarity value for the SW controlled pins, and setup the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	 * Extended Device Control reg with that info.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	 * This is needed because one of the SW controlled pins is used for
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	 * signal detection.  So this should be done before e1000_setup_pcs_link()
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	 * or e1000_phy_setup() is called.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	if (hw->mac_type == e1000_82543) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
		ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
					    1, &eeprom_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
			e_dbg("EEPROM Read Error\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
			return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
		ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
			    SWDPIO__EXT_SHIFT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		ew32(CTRL_EXT, ctrl_ext);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	/* Call the necessary subroutine to configure the link. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	ret_val = (hw->media_type == e1000_media_type_copper) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	    e1000_setup_copper_link(hw) : e1000_setup_fiber_serdes_link(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	/* Initialize the flow control address, type, and PAUSE timer
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	 * registers to their default values.  This is done even if flow
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	 * control is disabled, because it does not hurt anything to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	 * initialize these registers.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	e_dbg("Initializing the Flow Control address, type and timer regs\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	ew32(FCT, FLOW_CONTROL_TYPE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	ew32(FCTTV, hw->fc_pause_time);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
	/* Set the flow control receive threshold registers.  Normally,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	 * these registers will be set to a default threshold that may be
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	 * adjusted later by the driver's runtime code.  However, if the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	 * ability to transmit pause frames in not enabled, then these
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	 * registers will be set to 0.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	if (!(hw->fc & E1000_FC_TX_PAUSE)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
		ew32(FCRTL, 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
		ew32(FCRTH, 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
		/* We need to set up the Receive Threshold high and low water marks
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
		 * as well as (optionally) enabling the transmission of XON frames.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		if (hw->fc_send_xon) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
			ew32(FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
			ew32(FCRTH, hw->fc_high_water);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
			ew32(FCRTL, hw->fc_low_water);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
			ew32(FCRTH, hw->fc_high_water);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
 * e1000_setup_fiber_serdes_link - prepare fiber or serdes link
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
 * Manipulates Physical Coding Sublayer functions in order to configure
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
 * link. Assumes the hardware has been previously reset and the transmitter
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
 * and receiver are not enabled.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	u32 status;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	u32 txcw = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	u32 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	u32 signal = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	e_dbg("e1000_setup_fiber_serdes_link");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	/* On adapters with a MAC newer than 82544, SWDP 1 will be
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	 * set when the optics detect a signal. On older adapters, it will be
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	 * cleared when there is a signal.  This applies to fiber media only.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	 * If we're on serdes media, adjust the output amplitude to value
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	 * set in the EEPROM.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	if (hw->media_type == e1000_media_type_fiber)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
		signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	ret_val = e1000_adjust_serdes_amplitude(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	/* Take the link out of reset */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	ctrl &= ~(E1000_CTRL_LRST);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	/* Adjust VCO speed to improve BER performance */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	ret_val = e1000_set_vco_speed(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	e1000_config_collision_dist(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	/* Check for a software override of the flow control settings, and setup
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	 * the device accordingly.  If auto-negotiation is enabled, then software
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	 * will have to set the "PAUSE" bits to the correct value in the Tranmsit
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	 * Config Word Register (TXCW) and re-start auto-negotiation.  However, if
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	 * auto-negotiation is disabled, then software will have to manually
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	 * configure the two flow control enable bits in the CTRL register.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	 * The possible values of the "fc" parameter are:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	 *      0:  Flow control is completely disabled
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	 *      1:  Rx flow control is enabled (we can receive pause frames, but
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	 *          not send pause frames).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	 *      2:  Tx flow control is enabled (we can send pause frames but we do
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	 *          not support receiving pause frames).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	switch (hw->fc) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	case E1000_FC_NONE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		/* Flow control is completely disabled by a software over-ride. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	case E1000_FC_RX_PAUSE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
		/* RX Flow control is enabled and TX Flow control is disabled by a
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
		 * software over-ride. Since there really isn't a way to advertise
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
		 * that we are capable of RX Pause ONLY, we will advertise that we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		 * support both symmetric and asymmetric RX PAUSE. Later, we will
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
		 *  disable the adapter's ability to send PAUSE frames.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	case E1000_FC_TX_PAUSE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
		/* TX Flow control is enabled, and RX Flow control is disabled, by a
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
		 * software over-ride.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	case E1000_FC_FULL:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
		/* Flow control (both RX and TX) is enabled by a software over-ride. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
		e_dbg("Flow control param set incorrectly\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
		return -E1000_ERR_CONFIG;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	/* Since auto-negotiation is enabled, take the link out of reset (the link
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	 * will be in reset, because we previously reset the chip). This will
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	 * restart auto-negotiation.  If auto-negotiation is successful then the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	 * link-up status bit will be set and the flow control enable bits (RFCE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	 * and TFCE) will be set according to their negotiated value.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	e_dbg("Auto-negotiation enabled\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	ew32(TXCW, txcw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	hw->txcw = txcw;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	msleep(1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	/* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	 * indication in the Device Status Register.  Time-out if a link isn't
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	 * seen in 500 milliseconds seconds (Auto-negotiation should complete in
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	 * less than 500 milliseconds even if the other end is doing it in SW).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	 * For internal serdes, we just assume a signal is present, then poll.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	if (hw->media_type == e1000_media_type_internal_serdes ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	    (er32(CTRL) & E1000_CTRL_SWDPIN1) == signal) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
		e_dbg("Looking for Link\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
		for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
			msleep(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
			status = er32(STATUS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
			if (status & E1000_STATUS_LU)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
				break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
		if (i == (LINK_UP_TIMEOUT / 10)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
			e_dbg("Never got a valid link from auto-neg!!!\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
			hw->autoneg_failed = 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
			/* AutoNeg failed to achieve a link, so we'll call
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
			 * e1000_check_for_link. This routine will force the link up if
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
			 * we detect a signal. This will allow us to communicate with
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
			 * non-autonegotiating link partners.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
			ret_val = e1000_check_for_link(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
			if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
				e_dbg("Error while checking for link\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
			hw->autoneg_failed = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
			hw->autoneg_failed = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
			e_dbg("Valid Link Found\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
		e_dbg("No Signal Detected\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
 * e1000_copper_link_rtl_setup - Copper link setup for e1000_phy_rtl series.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
 * Commits changes to PHY configuration by calling e1000_phy_reset().
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
static s32 e1000_copper_link_rtl_setup(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	/* SW reset the PHY so all changes take effect */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
	ret_val = e1000_phy_reset(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
		e_dbg("Error Resetting the PHY\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
static s32 gbe_dhg_phy_setup(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	u32 ctrl_aux;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	switch (hw->phy_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	case e1000_phy_8211:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
		ret_val = e1000_copper_link_rtl_setup(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
			e_dbg("e1000_copper_link_rtl_setup failed!\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	case e1000_phy_8201:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		/* Set RMII mode */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
		ctrl_aux = er32(CTL_AUX);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
		ctrl_aux |= E1000_CTL_AUX_RMII;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
		ew32(CTL_AUX, ctrl_aux);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
		/* Disable the J/K bits required for receive */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
		ctrl_aux = er32(CTL_AUX);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
		ctrl_aux |= 0x4;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
		ctrl_aux &= ~0x2;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
		ew32(CTL_AUX, ctrl_aux);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		ret_val = e1000_copper_link_rtl_setup(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
			e_dbg("e1000_copper_link_rtl_setup failed!\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		e_dbg("Error Resetting the PHY\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
		return E1000_ERR_PHY_TYPE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
 * e1000_copper_link_preconfig - early configuration for copper
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
 * Make sure we have a valid PHY and change PHY mode before link setup.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
static s32 e1000_copper_link_preconfig(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	e_dbg("e1000_copper_link_preconfig");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	/* With 82543, we need to force speed and duplex on the MAC equal to what
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	 * the PHY speed and duplex configuration is. In addition, we need to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	 * perform a hardware reset on the PHY to take it out of reset.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	if (hw->mac_type > e1000_82543) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		ctrl |= E1000_CTRL_SLU;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
		ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		ctrl |=
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		    (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		ret_val = e1000_phy_hw_reset(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	/* Make sure we have a valid PHY */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	ret_val = e1000_detect_gig_phy(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		e_dbg("Error, did not detect valid phy.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
	e_dbg("Phy ID = %x\n", hw->phy_id);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	/* Set PHY to class A mode (if necessary) */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
	ret_val = e1000_set_phy_mode(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	if ((hw->mac_type == e1000_82545_rev_3) ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	    (hw->mac_type == e1000_82546_rev_3)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
		phy_data |= 0x00000008;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	if (hw->mac_type <= e1000_82543 ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	    hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	    hw->mac_type == e1000_82541_rev_2
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	    || hw->mac_type == e1000_82547_rev_2)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
		hw->phy_reset_disable = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
 * e1000_copper_link_igp_setup - Copper link setup for e1000_phy_igp series.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
static s32 e1000_copper_link_igp_setup(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	u32 led_ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	e_dbg("e1000_copper_link_igp_setup");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	if (hw->phy_reset_disable)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	ret_val = e1000_phy_reset(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
		e_dbg("Error Resetting the PHY\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	/* Wait 15ms for MAC to configure PHY from eeprom settings */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	msleep(15);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	/* Configure activity LED after PHY reset */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	led_ctrl = er32(LEDCTL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	led_ctrl &= IGP_ACTIVITY_LED_MASK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	ew32(LEDCTL, led_ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	/* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	if (hw->phy_type == e1000_phy_igp) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
		/* disable lplu d3 during driver init */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
		ret_val = e1000_set_d3_lplu_state(hw, false);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
			e_dbg("Error Disabling LPLU D3\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	/* Configure mdi-mdix settings */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
		hw->dsp_config_state = e1000_dsp_config_disabled;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
		/* Force MDI for earlier revs of the IGP PHY */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		phy_data &=
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		    ~(IGP01E1000_PSCR_AUTO_MDIX |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
		      IGP01E1000_PSCR_FORCE_MDI_MDIX);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
		hw->mdix = 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		hw->dsp_config_state = e1000_dsp_config_enabled;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		switch (hw->mdix) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		case 1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
			phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		case 2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
			phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		case 0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
		default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
			phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	/* set auto-master slave resolution settings */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	if (hw->autoneg) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		e1000_ms_type phy_ms_setting = hw->master_slave;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		if (hw->ffe_config_state == e1000_ffe_config_active)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
			hw->ffe_config_state = e1000_ffe_config_enabled;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		if (hw->dsp_config_state == e1000_dsp_config_activated)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
			hw->dsp_config_state = e1000_dsp_config_enabled;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		/* when autonegotiation advertisement is only 1000Mbps then we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
		 * should disable SmartSpeed and enable Auto MasterSlave
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		 * resolution as hardware default. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
		if (hw->autoneg_advertised == ADVERTISE_1000_FULL) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
			/* Disable SmartSpeed */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
					       &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
						phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
			/* Set auto Master/Slave resolution process */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
			    e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
			phy_data &= ~CR_1000T_MS_ENABLE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
			    e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
		/* load defaults for future use */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
		hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		    ((phy_data & CR_1000T_MS_VALUE) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		     e1000_ms_force_master :
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
		     e1000_ms_force_slave) : e1000_ms_auto;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		switch (phy_ms_setting) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		case e1000_ms_force_master:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
			phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		case e1000_ms_force_slave:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
			phy_data |= CR_1000T_MS_ENABLE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
			phy_data &= ~(CR_1000T_MS_VALUE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		case e1000_ms_auto:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
			phy_data &= ~CR_1000T_MS_ENABLE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
 * e1000_copper_link_mgp_setup - Copper link setup for e1000_phy_m88 series.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
static s32 e1000_copper_link_mgp_setup(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
	e_dbg("e1000_copper_link_mgp_setup");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	if (hw->phy_reset_disable)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	/* Enable CRS on TX. This must be set for half-duplex operation. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	/* Options:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	 *   MDI/MDI-X = 0 (default)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	 *   0 - Auto for all speeds
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	 *   1 - MDI mode
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	 *   2 - MDI-X mode
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	switch (hw->mdix) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	case 1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	case 2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	case 3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	case 0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	/* Options:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	 *   disable_polarity_correction = 0 (default)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	 *       Automatic Correction for Reversed Cable Polarity
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	 *   0 - Disabled
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	 *   1 - Enabled
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	if (hw->disable_polarity_correction == 1)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
	if (hw->phy_revision < M88E1011_I_REV_4) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
		/* Force TX_CLK in the Extended PHY Specific Control Register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
		 * to 25MHz clock.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
		    e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
				       &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
		if ((hw->phy_revision == E1000_REVISION_2) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
		    (hw->phy_id == M88E1111_I_PHY_ID)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
			/* Vidalia Phy, set the downshift counter to 5x */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
			phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
			ret_val = e1000_write_phy_reg(hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
						      M88E1000_EXT_PHY_SPEC_CTRL,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
						      phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
			/* Configure Master and Slave downshift values */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
				      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
			ret_val = e1000_write_phy_reg(hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
						      M88E1000_EXT_PHY_SPEC_CTRL,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
						      phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	/* SW Reset the PHY so all changes take effect */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	ret_val = e1000_phy_reset(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		e_dbg("Error Resetting the PHY\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
 * e1000_copper_link_autoneg - setup auto-neg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
 * Setup auto-negotiation and flow control advertisements,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
 * and then perform auto-negotiation.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
	e_dbg("e1000_copper_link_autoneg");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	/* Perform some bounds checking on the hw->autoneg_advertised
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	 * parameter.  If this variable is zero, then set it to the default.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	/* If autoneg_advertised is zero, we assume it was not defaulted
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
	 * by the calling code so we set to advertise full capability.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	if (hw->autoneg_advertised == 0)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
		hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	/* IFE/RTL8201N PHY only supports 10/100 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
	if (hw->phy_type == e1000_phy_8201)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
		hw->autoneg_advertised &= AUTONEG_ADVERTISE_10_100_ALL;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
	e_dbg("Reconfiguring auto-neg advertisement params\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	ret_val = e1000_phy_setup_autoneg(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
	if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
		e_dbg("Error Setting up Auto-Negotiation\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	e_dbg("Restarting Auto-Neg\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	 * the Auto Neg Restart bit in the PHY control register.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	/* Does the user want to wait for Auto-Neg to complete here, or
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
	 * check at a later time (for example, callback routine).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	if (hw->wait_autoneg_complete) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
		ret_val = e1000_wait_autoneg(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
			e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
			    ("Error while waiting for autoneg to complete\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
	hw->get_link_status = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
 * e1000_copper_link_postconfig - post link setup
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
 * Config the MAC and the PHY after link is up.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
 *   1) Set up the MAC to the current PHY speed/duplex
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
 *      if we are on 82543.  If we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
 *      are on newer silicon, we only need to configure
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
 *      collision distance in the Transmit Control Register.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
 *   2) Set up flow control on the MAC to that established with
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
 *      the link partner.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
 *   3) Config DSP to improve Gigabit link quality for some PHY revisions.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
static s32 e1000_copper_link_postconfig(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	e_dbg("e1000_copper_link_postconfig");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
	if ((hw->mac_type >= e1000_82544) && (hw->mac_type != e1000_ce4100)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
		e1000_config_collision_dist(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
		ret_val = e1000_config_mac_to_phy(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
			e_dbg("Error configuring MAC to PHY settings\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	ret_val = e1000_config_fc_after_link_up(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
	if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
		e_dbg("Error Configuring Flow Control\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
	/* Config DSP to improve Giga link quality */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	if (hw->phy_type == e1000_phy_igp) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
		ret_val = e1000_config_dsp_after_link_change(hw, true);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
			e_dbg("Error Configuring DSP after link up\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
 * e1000_setup_copper_link - phy/speed/duplex setting
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
 * Detects which PHY is present and sets up the speed and duplex
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
static s32 e1000_setup_copper_link(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	u16 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	e_dbg("e1000_setup_copper_link");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	/* Check if it is a valid PHY and set PHY mode if necessary. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	ret_val = e1000_copper_link_preconfig(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	if (hw->phy_type == e1000_phy_igp) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
		ret_val = e1000_copper_link_igp_setup(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	} else if (hw->phy_type == e1000_phy_m88) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
		ret_val = e1000_copper_link_mgp_setup(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
		ret_val = gbe_dhg_phy_setup(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
			e_dbg("gbe_dhg_phy_setup failed!\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	if (hw->autoneg) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
		/* Setup autoneg and flow control advertisement
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
		 * and perform autonegotiation */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
		ret_val = e1000_copper_link_autoneg(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
		/* PHY will be set to 10H, 10F, 100H,or 100F
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		 * depending on value from forced_speed_duplex. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		e_dbg("Forcing speed and duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
		ret_val = e1000_phy_force_speed_duplex(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
			e_dbg("Error Forcing Speed and Duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	/* Check link status. Wait up to 100 microseconds for link to become
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	 * valid.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	for (i = 0; i < 10; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
		if (phy_data & MII_SR_LINK_STATUS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
			/* Config the MAC and PHY after link is up */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
			ret_val = e1000_copper_link_postconfig(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
			e_dbg("Valid link established!!!\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
			return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
		udelay(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	e_dbg("Unable to establish link!!!\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
 * e1000_phy_setup_autoneg - phy settings
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
 * Configures PHY autoneg and flow control advertisement settings
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	u16 mii_autoneg_adv_reg;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	u16 mii_1000t_ctrl_reg;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	e_dbg("e1000_phy_setup_autoneg");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	/* Read the MII 1000Base-T Control Register (Address 9). */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
	ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
	else if (hw->phy_type == e1000_phy_8201)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	/* Need to parse both autoneg_advertised and fc and set up
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	 * the appropriate PHY registers.  First we will parse for
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	 * autoneg_advertised software override.  Since we can advertise
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
	 * a plethora of combinations, we need to check each bit
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	 * individually.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
	 * the  1000Base-T Control Register (Address 9).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
	mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	e_dbg("autoneg_advertised %x\n", hw->autoneg_advertised);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	/* Do we want to advertise 10 Mb Half Duplex? */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
		e_dbg("Advertise 10mb Half duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	/* Do we want to advertise 10 Mb Full Duplex? */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
		e_dbg("Advertise 10mb Full duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
	/* Do we want to advertise 100 Mb Half Duplex? */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
		e_dbg("Advertise 100mb Half duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
	/* Do we want to advertise 100 Mb Full Duplex? */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
		e_dbg("Advertise 100mb Full duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		    ("Advertise 1000mb Half duplex requested, request denied!\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	/* Do we want to advertise 1000 Mb Full Duplex? */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		e_dbg("Advertise 1000mb Full duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	/* Check for a software override of the flow control settings, and
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	 * setup the PHY advertisement registers accordingly.  If
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	 * auto-negotiation is enabled, then software will have to set the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	 * "PAUSE" bits to the correct value in the Auto-Negotiation
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
	 * The possible values of the "fc" parameter are:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	 *      0:  Flow control is completely disabled
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
	 *      1:  Rx flow control is enabled (we can receive pause frames
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	 *          but not send pause frames).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	 *      2:  Tx flow control is enabled (we can send pause frames
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
	 *          but we do not support receiving pause frames).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	 *  other:  No software override.  The flow control configuration
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
	 *          in the EEPROM is used.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
	switch (hw->fc) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
	case E1000_FC_NONE:	/* 0 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
		/* Flow control (RX & TX) is completely disabled by a
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
		 * software over-ride.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	case E1000_FC_RX_PAUSE:	/* 1 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
		/* RX Flow control is enabled, and TX Flow control is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		 * disabled, by a software over-ride.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		/* Since there really isn't a way to advertise that we are
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		 * capable of RX Pause ONLY, we will advertise that we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		 * support both symmetric and asymmetric RX PAUSE.  Later
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
		 * (in e1000_config_fc_after_link_up) we will disable the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
		 *hw's ability to send PAUSE frames.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
	case E1000_FC_TX_PAUSE:	/* 2 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		/* TX Flow control is enabled, and RX Flow control is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		 * disabled, by a software over-ride.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	case E1000_FC_FULL:	/* 3 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		/* Flow control (both RX and TX) is enabled by a software
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		 * over-ride.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
		e_dbg("Flow control param set incorrectly\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
		return -E1000_ERR_CONFIG;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
	e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	if (hw->phy_type == e1000_phy_8201) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
		mii_1000t_ctrl_reg = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		                              mii_1000t_ctrl_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
 * e1000_phy_force_speed_duplex - force link settings
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
 * Force PHY speed and duplex settings to hw->forced_speed_duplex
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	u16 mii_ctrl_reg;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	u16 mii_status_reg;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
	u16 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	e_dbg("e1000_phy_force_speed_duplex");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	/* Turn off Flow control if we are forcing speed and duplex. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	hw->fc = E1000_FC_NONE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	e_dbg("hw->fc = %d\n", hw->fc);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	/* Read the Device Control Register. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	/* Set the bits to Force Speed and Duplex in the Device Ctrl Reg. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	ctrl &= ~(DEVICE_SPEED_MASK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
	/* Clear the Auto Speed Detect Enable bit. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	ctrl &= ~E1000_CTRL_ASDE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
	/* Read the MII Control Register. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	/* We need to disable autoneg in order to force link and duplex. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	/* Are we forcing Full or Half Duplex? */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	if (hw->forced_speed_duplex == e1000_100_full ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	    hw->forced_speed_duplex == e1000_10_full) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
		/* We want to force full duplex so we SET the full duplex bits in the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
		 * Device and MII Control Registers.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		ctrl |= E1000_CTRL_FD;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		mii_ctrl_reg |= MII_CR_FULL_DUPLEX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
		e_dbg("Full Duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		/* We want to force half duplex so we CLEAR the full duplex bits in
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
		 * the Device and MII Control Registers.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		ctrl &= ~E1000_CTRL_FD;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
		mii_ctrl_reg &= ~MII_CR_FULL_DUPLEX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		e_dbg("Half Duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	/* Are we forcing 100Mbps??? */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	if (hw->forced_speed_duplex == e1000_100_full ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	    hw->forced_speed_duplex == e1000_100_half) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		/* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		ctrl |= E1000_CTRL_SPD_100;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		mii_ctrl_reg |= MII_CR_SPEED_100;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		e_dbg("Forcing 100mb ");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
		/* Set the 10Mb bit and turn off the 1000Mb and 100Mb bits. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
		mii_ctrl_reg |= MII_CR_SPEED_10;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
		mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
		e_dbg("Forcing 10mb ");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	e1000_config_collision_dist(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	/* Write the configured values back to the Device Control Reg. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
	ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
	if (hw->phy_type == e1000_phy_m88) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		/* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
		 * forced whenever speed are duplex are forced.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		e_dbg("M88E1000 PSCR: %x\n", phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		/* Need to reset the PHY or these changes will be ignored */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		mii_ctrl_reg |= MII_CR_RESET;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		/* Disable MDI-X support for 10/100 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
		/* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		 * forced whenever speed or duplex are forced.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
		phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	/* Write back the modified PHY MII control register. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
	udelay(1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	/* The wait_autoneg_complete flag may be a little misleading here.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	 * Since we are forcing speed and duplex, Auto-Neg is not enabled.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	 * But we do want to delay for a period while forcing only so we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	 * don't generate false No Link messages.  So we will wait here
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	 * only if the user has set wait_autoneg_complete to 1, which is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	 * the default.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	if (hw->wait_autoneg_complete) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
		/* We will wait for autoneg to complete. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
		e_dbg("Waiting for forced speed/duplex link.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
		mii_status_reg = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
		/* We will wait for autoneg to complete or 4.5 seconds to expire. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
		for (i = PHY_FORCE_TIME; i > 0; i--) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
			/* Read the MII Status Register and wait for Auto-Neg Complete bit
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
			 * to be set.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
			if (mii_status_reg & MII_SR_LINK_STATUS)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
				break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
			msleep(100);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
		if ((i == 0) && (hw->phy_type == e1000_phy_m88)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
			/* We didn't get link.  Reset the DSP and wait again for link. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
			ret_val = e1000_phy_reset_dsp(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
			if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
				e_dbg("Error Resetting PHY DSP\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
		/* This loop will early-out if the link condition has been met.  */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
		for (i = PHY_FORCE_TIME; i > 0; i--) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
			if (mii_status_reg & MII_SR_LINK_STATUS)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
				break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
			msleep(100);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
			/* Read the MII Status Register and wait for Auto-Neg Complete bit
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
			 * to be set.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	if (hw->phy_type == e1000_phy_m88) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		/* Because we reset the PHY above, we need to re-force TX_CLK in the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		 * Extended PHY Specific Control Register to 25MHz clock.  This value
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
		 * defaults back to a 2.5MHz clock when the PHY is reset.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
		    e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
				       &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
		    e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
					phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
		/* In addition, because of the s/w reset above, we need to enable CRS on
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		 * TX.  This must be set for both full and half duplex operation.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
		phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
		if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
		    && (!hw->autoneg)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
		    && (hw->forced_speed_duplex == e1000_10_full
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
			|| hw->forced_speed_duplex == e1000_10_half)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
			ret_val = e1000_polarity_reversal_workaround(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
 * e1000_config_collision_dist - set collision distance register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
 * Sets the collision distance in the Transmit Control register.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
 * Link should have been established previously. Reads the speed and duplex
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
 * information from the Device Status register.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
void e1000_config_collision_dist(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
	u32 tctl, coll_dist;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	e_dbg("e1000_config_collision_dist");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	if (hw->mac_type < e1000_82543)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
		coll_dist = E1000_COLLISION_DISTANCE_82542;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	else
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
		coll_dist = E1000_COLLISION_DISTANCE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
	tctl = er32(TCTL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	tctl &= ~E1000_TCTL_COLD;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
	tctl |= coll_dist << E1000_COLD_SHIFT;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	ew32(TCTL, tctl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
 * e1000_config_mac_to_phy - sync phy and mac settings
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
 * @mii_reg: data to write to the MII control register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
 * Sets MAC speed and duplex settings to reflect the those in the PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
 * The contents of the PHY register containing the needed information need to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
 * be passed in.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	e_dbg("e1000_config_mac_to_phy");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	/* 82544 or newer MAC, Auto Speed Detection takes care of
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
	 * MAC speed/duplex configuration.*/
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	if ((hw->mac_type >= e1000_82544) && (hw->mac_type != e1000_ce4100))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	/* Read the Device Control Register and set the bits to Force Speed
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
	 * and Duplex.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
	ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
	ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	switch (hw->phy_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	case e1000_phy_8201:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
		ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
		if (phy_data & RTL_PHY_CTRL_FD)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
			ctrl |= E1000_CTRL_FD;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		else
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
			ctrl &= ~E1000_CTRL_FD;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
		if (phy_data & RTL_PHY_CTRL_SPD_100)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
			ctrl |= E1000_CTRL_SPD_100;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
		else
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
			ctrl |= E1000_CTRL_SPD_10;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
		e1000_config_collision_dist(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
		/* Set up duplex in the Device Control and Transmit Control
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
		 * registers depending on negotiated values.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
		                             &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
		if (phy_data & M88E1000_PSSR_DPLX)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
			ctrl |= E1000_CTRL_FD;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
		else
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
			ctrl &= ~E1000_CTRL_FD;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
		e1000_config_collision_dist(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		/* Set up speed in the Device Control register depending on
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
		 * negotiated values.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
		if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
			ctrl |= E1000_CTRL_SPD_1000;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
		else if ((phy_data & M88E1000_PSSR_SPEED) ==
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
		         M88E1000_PSSR_100MBS)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
			ctrl |= E1000_CTRL_SPD_100;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	/* Write the configured values back to the Device Control Reg. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
 * e1000_force_mac_fc - force flow control settings
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
 * Forces the MAC's flow control settings.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
 * Sets the TFCE and RFCE bits in the device control register to reflect
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
 * the adapter settings. TFCE and RFCE need to be explicitly set by
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
 * software when a Copper PHY is used because autonegotiation is managed
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
 * by the PHY rather than the MAC. Software must also configure these
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
 * bits when link is forced on a fiber connection.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
s32 e1000_force_mac_fc(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	e_dbg("e1000_force_mac_fc");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	/* Get the current configuration of the Device Control Register */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
	ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	/* Because we didn't get link via the internal auto-negotiation
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	 * mechanism (we either forced link or we got link via PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	 * auto-neg), we have to manually enable/disable transmit an
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	 * receive flow control.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	 * The "Case" statement below enables/disable flow control
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
	 * according to the "hw->fc" parameter.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
	 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	 * The possible values of the "fc" parameter are:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
	 *      0:  Flow control is completely disabled
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	 *      1:  Rx flow control is enabled (we can receive pause
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
	 *          frames but not send pause frames).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
	 *      2:  Tx flow control is enabled (we can send pause frames
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
	 *          frames but we do not receive pause frames).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
	 *      3:  Both Rx and TX flow control (symmetric) is enabled.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	 *  other:  No other values should be possible at this point.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
	switch (hw->fc) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
	case E1000_FC_NONE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
	case E1000_FC_RX_PAUSE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		ctrl &= (~E1000_CTRL_TFCE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
		ctrl |= E1000_CTRL_RFCE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
	case E1000_FC_TX_PAUSE:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
		ctrl &= (~E1000_CTRL_RFCE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
		ctrl |= E1000_CTRL_TFCE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	case E1000_FC_FULL:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
		e_dbg("Flow control param set incorrectly\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
		return -E1000_ERR_CONFIG;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	/* Disable TX Flow Control for 82542 (rev 2.0) */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	if (hw->mac_type == e1000_82542_rev2_0)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
		ctrl &= (~E1000_CTRL_TFCE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
 * e1000_config_fc_after_link_up - configure flow control after autoneg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
 * Configures flow control settings after link is established
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
 * Should be called immediately after a valid link has been established.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
 * Forces MAC flow control settings if link was forced. When in MII/GMII mode
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
 * and autonegotiation is enabled, the MAC flow control settings will be set
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
 * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
 * and RFCE bits will be automatically set to the negotiated flow control mode.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	u16 mii_status_reg;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	u16 mii_nway_adv_reg;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	u16 mii_nway_lp_ability_reg;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	u16 speed;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	u16 duplex;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	e_dbg("e1000_config_fc_after_link_up");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	/* Check for the case where we have fiber media and auto-neg failed
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	 * so we had to force link.  In this case, we need to force the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
	 * configuration of the MAC to match the "fc" parameter.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	    || ((hw->media_type == e1000_media_type_internal_serdes)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
		&& (hw->autoneg_failed))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
	    || ((hw->media_type == e1000_media_type_copper)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
		&& (!hw->autoneg))) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
		ret_val = e1000_force_mac_fc(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
			e_dbg("Error forcing flow control settings\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
	/* Check for the case where we have copper media and auto-neg is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
	 * enabled.  In this case, we need to check and see if Auto-Neg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
	 * has completed, and if so, how the PHY and link partner has
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	 * flow control configured.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
	if ((hw->media_type == e1000_media_type_copper) && hw->autoneg) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
		/* Read the MII Status Register and check to see if AutoNeg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
		 * has completed.  We read this twice because this reg has
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
		 * some "sticky" (latched) bits.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
		if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
			/* The AutoNeg process has completed, so we now need to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
			 * read both the Auto Negotiation Advertisement Register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
			 * (Address 4) and the Auto_Negotiation Base Page Ability
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
			 * Register (Address 5) to determine how flow control was
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
			 * negotiated.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
			ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
						     &mii_nway_adv_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
			ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
						     &mii_nway_lp_ability_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
			/* Two bits in the Auto Negotiation Advertisement Register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
			 * (Address 4) and two bits in the Auto Negotiation Base
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
			 * Page Ability Register (Address 5) determine flow control
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
			 * for both the PHY and the link partner.  The following
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
			 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
			 * 1999, describes these PAUSE resolution bits and how flow
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
			 * control is determined based upon these settings.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
			 * NOTE:  DC = Don't Care
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
			 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
			 *   LOCAL DEVICE  |   LINK PARTNER
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
			 *-------|---------|-------|---------|--------------------
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
			 *   0   |    0    |  DC   |   DC    | E1000_FC_NONE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
			 *   0   |    1    |   0   |   DC    | E1000_FC_NONE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
			 *   0   |    1    |   1   |    0    | E1000_FC_NONE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
			 *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
			 *   1   |    0    |   0   |   DC    | E1000_FC_NONE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
			 *   1   |    1    |   0   |    0    | E1000_FC_NONE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
			 *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
			 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
			/* Are both PAUSE bits set to 1?  If so, this implies
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
			 * Symmetric Flow Control is enabled at both ends.  The
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
			 * ASM_DIR bits are irrelevant per the spec.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
			 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
			 * For Symmetric Flow Control:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
			 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
			 *   LOCAL DEVICE  |   LINK PARTNER
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
			 *-------|---------|-------|---------|--------------------
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
			 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
			if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
			    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
				/* Now we need to check if the user selected RX ONLY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
				 * of pause frames.  In this case, we had to advertise
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
				 * FULL flow control because we could not advertise RX
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
				 * ONLY. Hence, we must now check to see if we need to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
				 * turn OFF  the TRANSMISSION of PAUSE frames.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
				 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
				if (hw->original_fc == E1000_FC_FULL) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
					hw->fc = E1000_FC_FULL;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
					e_dbg("Flow Control = FULL.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
				} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
					hw->fc = E1000_FC_RX_PAUSE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
					e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
					    ("Flow Control = RX PAUSE frames only.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
				}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
			/* For receiving PAUSE frames ONLY.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
			 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
			 *   LOCAL DEVICE  |   LINK PARTNER
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
			 *-------|---------|-------|---------|--------------------
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
			 *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
			 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
			else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
				 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
			{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
				hw->fc = E1000_FC_TX_PAUSE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
				e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
				    ("Flow Control = TX PAUSE frames only.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
			/* For transmitting PAUSE frames ONLY.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
			 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
			 *   LOCAL DEVICE  |   LINK PARTNER
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
			 *-------|---------|-------|---------|--------------------
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
			 *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
			 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
			else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
				 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
			{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
				hw->fc = E1000_FC_RX_PAUSE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
				e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
				    ("Flow Control = RX PAUSE frames only.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
			/* Per the IEEE spec, at this point flow control should be
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
			 * disabled.  However, we want to consider that we could
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
			 * be connected to a legacy switch that doesn't advertise
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
			 * desired flow control, but can be forced on the link
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
			 * partner.  So if we advertised no flow control, that is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
			 * what we will resolve to.  If we advertised some kind of
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
			 * receive capability (Rx Pause Only or Full Flow Control)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
			 * and the link partner advertised none, we will configure
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
			 * ourselves to enable Rx Flow Control only.  We can do
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
			 * this safely for two reasons:  If the link partner really
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
			 * didn't want flow control enabled, and we enable Rx, no
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
			 * harm done since we won't be receiving any PAUSE frames
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
			 * anyway.  If the intent on the link partner was to have
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
			 * flow control enabled, then by us enabling RX only, we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
			 * can at least receive pause frames and process them.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
			 * This is a good idea because in most cases, since we are
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
			 * predominantly a server NIC, more times than not we will
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
			 * be asked to delay transmission of packets than asking
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
			 * our link partner to pause transmission of frames.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
			else if ((hw->original_fc == E1000_FC_NONE ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
				  hw->original_fc == E1000_FC_TX_PAUSE) ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
				 hw->fc_strict_ieee) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
				hw->fc = E1000_FC_NONE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
				e_dbg("Flow Control = NONE.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
			} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
				hw->fc = E1000_FC_RX_PAUSE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
				e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
				    ("Flow Control = RX PAUSE frames only.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
			/* Now we need to do one last check...  If we auto-
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
			 * negotiated to HALF DUPLEX, flow control should not be
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
			 * enabled per IEEE 802.3 spec.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
			if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
				e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
				    ("Error getting link speed and duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
			if (duplex == HALF_DUPLEX)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
				hw->fc = E1000_FC_NONE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
			/* Now we call a subroutine to actually force the MAC
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
			 * controller to use the correct flow control settings.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
			ret_val = e1000_force_mac_fc(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
			if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
				e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
				    ("Error forcing flow control settings\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
			e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
			    ("Copper PHY and Auto Neg has not completed.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
 * e1000_check_for_serdes_link_generic - Check for link (Serdes)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
 * @hw: pointer to the HW structure
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
 * Checks for link up on the hardware.  If link is not up and we have
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
 * a signal, then we need to force link up.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
static s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	u32 rxcw;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	u32 status;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	s32 ret_val = E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	e_dbg("e1000_check_for_serdes_link_generic");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
	ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
	status = er32(STATUS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
	rxcw = er32(RXCW);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	/*
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	 * If we don't have link (auto-negotiation failed or link partner
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
	 * cannot auto-negotiate), and our link partner is not trying to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	 * auto-negotiate with us (we are receiving idles or data),
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	 * we need to force link up. We also need to give auto-negotiation
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	 * time to complete.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
		if (hw->autoneg_failed == 0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
			hw->autoneg_failed = 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
			goto out;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		e_dbg("NOT RXing /C/, disable AutoNeg and force link.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		/* Disable auto-negotiation in the TXCW register */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
		/* Force link-up and also force full-duplex. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
		ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
		/* Configure Flow Control after forcing link up. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
		ret_val = e1000_config_fc_after_link_up(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
			e_dbg("Error configuring flow control\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
			goto out;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		/*
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
		 * If we are forcing link and we are receiving /C/ ordered
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
		 * sets, re-enable auto-negotiation in the TXCW register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
		 * and disable forced link in the Device Control register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
		 * in an attempt to auto-negotiate with our link partner.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
		e_dbg("RXing /C/, enable AutoNeg and stop forcing link.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		ew32(TXCW, hw->txcw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
		hw->serdes_has_link = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
		/*
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
		 * If we force link for non-auto-negotiation switch, check
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
		 * link status based on MAC synchronization for internal
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
		 * serdes media type.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
		/* SYNCH bit and IV bit are sticky. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
		udelay(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
		rxcw = er32(RXCW);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
		if (rxcw & E1000_RXCW_SYNCH) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
			if (!(rxcw & E1000_RXCW_IV)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
				hw->serdes_has_link = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
				e_dbg("SERDES: Link up - forced.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
			hw->serdes_has_link = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
			e_dbg("SERDES: Link down - force failed.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	if (E1000_TXCW_ANE & er32(TXCW)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
		status = er32(STATUS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
		if (status & E1000_STATUS_LU) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
			/* SYNCH bit and IV bit are sticky, so reread rxcw. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
			udelay(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
			rxcw = er32(RXCW);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
			if (rxcw & E1000_RXCW_SYNCH) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
				if (!(rxcw & E1000_RXCW_IV)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
					hw->serdes_has_link = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
					e_dbg("SERDES: Link up - autoneg "
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
						 "completed successfully.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
				} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
					hw->serdes_has_link = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
					e_dbg("SERDES: Link down - invalid"
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
						 "codewords detected in autoneg.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
				}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
			} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
				hw->serdes_has_link = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
				e_dbg("SERDES: Link down - no sync.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
			hw->serdes_has_link = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
			e_dbg("SERDES: Link down - autoneg failed\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
      out:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
	return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
 * e1000_check_for_link
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
 * Checks to see if the link status of the hardware has changed.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
 * Called by any function that needs to check the link status of the adapter.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
s32 e1000_check_for_link(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
	u32 rxcw = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
	u32 status;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	u32 rctl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	u32 icr;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
	u32 signal = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	e_dbg("e1000_check_for_link");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	status = er32(STATUS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
	/* On adapters with a MAC newer than 82544, SW Definable pin 1 will be
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	 * set when the optics detect a signal. On older adapters, it will be
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	 * cleared when there is a signal.  This applies to fiber media only.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	if ((hw->media_type == e1000_media_type_fiber) ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
	    (hw->media_type == e1000_media_type_internal_serdes)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
		rxcw = er32(RXCW);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
		if (hw->media_type == e1000_media_type_fiber) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
			signal =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
			    (hw->mac_type >
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
			     e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
			if (status & E1000_STATUS_LU)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
				hw->get_link_status = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	/* If we have a copper PHY then we only want to go out to the PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
	 * registers to see if Auto-Neg has completed and/or if our link
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	 * status has changed.  The get_link_status flag will be set if we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	 * receive a Link Status Change interrupt or we have Rx Sequence
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
	 * Errors.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
	if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
		/* First we want to see if the MII Status Register reports
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		 * link.  If so, then we want to get the current speed/duplex
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
		 * of the PHY.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		 * Read the register twice since the link bit is sticky.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
		if (phy_data & MII_SR_LINK_STATUS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
			hw->get_link_status = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
			/* Check if there was DownShift, must be checked immediately after
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
			 * link-up */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
			e1000_check_downshift(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
			/* If we are on 82544 or 82543 silicon and speed/duplex
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
			 * are forced to 10H or 10F, then we will implement the polarity
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
			 * reversal workaround.  We disable interrupts first, and upon
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
			 * returning, place the devices interrupt state to its previous
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
			 * value except for the link status change interrupt which will
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
			 * happen due to the execution of this workaround.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
			if ((hw->mac_type == e1000_82544
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
			     || hw->mac_type == e1000_82543) && (!hw->autoneg)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
			    && (hw->forced_speed_duplex == e1000_10_full
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
				|| hw->forced_speed_duplex == e1000_10_half)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
				ew32(IMC, 0xffffffff);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
				ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
				    e1000_polarity_reversal_workaround(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
				icr = er32(ICR);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
				ew32(ICS, (icr & ~E1000_ICS_LSC));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
				ew32(IMS, IMS_ENABLE_MASK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
			/* No link detected */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
			e1000_config_dsp_after_link_change(hw, false);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
			return 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
		/* If we are forcing speed/duplex, then we simply return since
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
		 * we have already determined whether we have link or not.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		if (!hw->autoneg)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
			return -E1000_ERR_CONFIG;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
		/* optimize the dsp settings for the igp phy */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
		e1000_config_dsp_after_link_change(hw, true);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		/* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
		 * have Si on board that is 82544 or newer, Auto
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		 * Speed Detection takes care of MAC speed/duplex
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
		 * configuration.  So we only need to configure Collision
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		 * Distance in the MAC.  Otherwise, we need to force
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
		 * speed/duplex on the MAC to the current PHY speed/duplex
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
		 * settings.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
		if ((hw->mac_type >= e1000_82544) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
		    (hw->mac_type != e1000_ce4100))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
			e1000_config_collision_dist(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
		else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
			ret_val = e1000_config_mac_to_phy(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
			if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
				e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
				    ("Error configuring MAC to PHY settings\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		/* Configure Flow Control now that Auto-Neg has completed. First, we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		 * need to restore the desired flow control settings because we may
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
		 * have had to re-autoneg with a different link partner.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
		ret_val = e1000_config_fc_after_link_up(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
			e_dbg("Error configuring flow control\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
		/* At this point we know that we are on copper and we have
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
		 * auto-negotiated link.  These are conditions for checking the link
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
		 * partner capability register.  We use the link speed to determine if
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
		 * TBI compatibility needs to be turned on or off.  If the link is not
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
		 * at gigabit speed, then TBI compatibility is not needed.  If we are
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
		 * at gigabit speed, we turn on TBI compatibility.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
		if (hw->tbi_compatibility_en) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
			u16 speed, duplex;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
			if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
				e_dbg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
				    ("Error getting link speed and duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
			if (speed != SPEED_1000) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
				/* If link speed is not set to gigabit speed, we do not need
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
				 * to enable TBI compatibility.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
				 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
				if (hw->tbi_compatibility_on) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
					/* If we previously were in the mode, turn it off. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
					rctl = er32(RCTL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
					rctl &= ~E1000_RCTL_SBP;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
					ew32(RCTL, rctl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
					hw->tbi_compatibility_on = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
				}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
			} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
				/* If TBI compatibility is was previously off, turn it on. For
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
				 * compatibility with a TBI link partner, we will store bad
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
				 * packets. Some frames have an additional byte on the end and
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
				 * will look like CRC errors to to the hardware.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
				 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
				if (!hw->tbi_compatibility_on) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
					hw->tbi_compatibility_on = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
					rctl = er32(RCTL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
					rctl |= E1000_RCTL_SBP;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
					ew32(RCTL, rctl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
				}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
	if ((hw->media_type == e1000_media_type_fiber) ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
	    (hw->media_type == e1000_media_type_internal_serdes))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
		e1000_check_for_serdes_link_generic(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
 * e1000_get_speed_and_duplex
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
 * @speed: Speed of the connection
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
 * @duplex: Duplex setting of the connection
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
 * Detects the current speed and duplex settings of the hardware.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
	u32 status;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	e_dbg("e1000_get_speed_and_duplex");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
	if (hw->mac_type >= e1000_82543) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
		status = er32(STATUS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
		if (status & E1000_STATUS_SPEED_1000) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
			*speed = SPEED_1000;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
			e_dbg("1000 Mbs, ");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
		} else if (status & E1000_STATUS_SPEED_100) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
			*speed = SPEED_100;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
			e_dbg("100 Mbs, ");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
			*speed = SPEED_10;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
			e_dbg("10 Mbs, ");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
		if (status & E1000_STATUS_FD) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
			*duplex = FULL_DUPLEX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
			e_dbg("Full Duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
			*duplex = HALF_DUPLEX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
			e_dbg(" Half Duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
		e_dbg("1000 Mbs, Full Duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
		*speed = SPEED_1000;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
		*duplex = FULL_DUPLEX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	/* IGP01 PHY may advertise full duplex operation after speed downgrade even
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	 * if it is operating at half duplex.  Here we set the duplex settings to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	 * match the duplex in the link partner's capabilities.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
	if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
		ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
		if (!(phy_data & NWAY_ER_LP_NWAY_CAPS))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
			*duplex = HALF_DUPLEX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
		else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
			    e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
			if ((*speed == SPEED_100
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
			     && !(phy_data & NWAY_LPAR_100TX_FD_CAPS))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
			    || (*speed == SPEED_10
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
				&& !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
				*duplex = HALF_DUPLEX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
 * e1000_wait_autoneg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
 * Blocks until autoneg completes or times out (~4.5 seconds)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
static s32 e1000_wait_autoneg(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	u16 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	e_dbg("e1000_wait_autoneg");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
	e_dbg("Waiting for Auto-Neg to complete.\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	/* We will wait for autoneg to complete or 4.5 seconds to expire. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
		/* Read the MII Status Register and wait for Auto-Neg
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
		 * Complete bit to be set.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
		if (phy_data & MII_SR_AUTONEG_COMPLETE) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
			return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
		msleep(100);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
 * e1000_raise_mdi_clk - Raises the Management Data Clock
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
 * @ctrl: Device control register's current value
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	/* Raise the clock input to the Management Data Clock (by setting the MDC
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	 * bit), and then delay 10 microseconds.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	ew32(CTRL, (*ctrl | E1000_CTRL_MDC));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
	E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
	udelay(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
 * e1000_lower_mdi_clk - Lowers the Management Data Clock
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
 * @ctrl: Device control register's current value
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
	/* Lower the clock input to the Management Data Clock (by clearing the MDC
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
	 * bit), and then delay 10 microseconds.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
	ew32(CTRL, (*ctrl & ~E1000_CTRL_MDC));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
	E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	udelay(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
 * e1000_shift_out_mdi_bits - Shifts data bits out to the PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
 * @data: Data to send out to the PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
 * @count: Number of bits to shift out
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
 * Bits are shifted out in MSB to LSB order.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data, u16 count)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
	u32 mask;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
	/* We need to shift "count" number of bits out to the PHY. So, the value
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
	 * in the "data" parameter will be shifted out to the PHY one bit at a
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	 * time. In order to do this, "data" must be broken down into bits.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
	mask = 0x01;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
	mask <<= (count - 1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
	/* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
	ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	while (mask) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
		/* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
		 * then raising and lowering the Management Data Clock. A "0" is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
		 * shifted out to the PHY by setting the MDIO bit to "0" and then
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
		 * raising and lowering the clock.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
		if (data & mask)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
			ctrl |= E1000_CTRL_MDIO;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
		else
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
			ctrl &= ~E1000_CTRL_MDIO;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
		ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
		udelay(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
		e1000_raise_mdi_clk(hw, &ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
		e1000_lower_mdi_clk(hw, &ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
		mask = mask >> 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
 * e1000_shift_in_mdi_bits - Shifts data bits in from the PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
 * Bits are shifted in in MSB to LSB order.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	u32 ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
	u16 data = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
	u8 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	/* In order to read a register from the PHY, we need to shift in a total
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
	 * of 18 bits from the PHY. The first two bit (turnaround) times are used
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	 * to avoid contention on the MDIO pin when a read operation is performed.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	 * These two bits are ignored by us and thrown away. Bits are "shifted in"
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
	 * by raising the input to the Management Data Clock (setting the MDC bit),
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	 * and then reading the value of the MDIO bit.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	/* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
	ctrl &= ~E1000_CTRL_MDIO_DIR;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	ctrl &= ~E1000_CTRL_MDIO;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
	ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
	E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
	/* Raise and Lower the clock before reading in the data. This accounts for
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
	 * the turnaround bits. The first clock occurred when we clocked out the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
	 * last bit of the Register Address.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
	e1000_raise_mdi_clk(hw, &ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
	e1000_lower_mdi_clk(hw, &ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
	for (data = 0, i = 0; i < 16; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
		data = data << 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		e1000_raise_mdi_clk(hw, &ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
		ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		/* Check to see if we shifted in a "1". */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
		if (ctrl & E1000_CTRL_MDIO)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
			data |= 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
		e1000_lower_mdi_clk(hw, &ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
	e1000_raise_mdi_clk(hw, &ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
	e1000_lower_mdi_clk(hw, &ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	return data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
 * e1000_read_phy_reg - read a phy register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
 * @reg_addr: address of the PHY register to read
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
 * Reads the value from a PHY register, if the value is on a specific non zero
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
 * page, sets the page first.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
	u32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	e_dbg("e1000_read_phy_reg");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	if ((hw->phy_type == e1000_phy_igp) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
						 (u16) reg_addr);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
					phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
	return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
				 u16 *phy_data)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	u32 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
	u32 mdic = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
	const u32 phy_addr = (hw->mac_type == e1000_ce4100) ? hw->phy_addr : 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
	e_dbg("e1000_read_phy_reg_ex");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
		e_dbg("PHY Address %d is out of range\n", reg_addr);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
		return -E1000_ERR_PARAM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	if (hw->mac_type > e1000_82543) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
		/* Set up Op-code, Phy Address, and register address in the MDI
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
		 * Control register.  The MAC will take care of interfacing with the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
		 * PHY to retrieve the desired data.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
		if (hw->mac_type == e1000_ce4100) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
			mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
				(INTEL_CE_GBE_MDIC_OP_READ) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
				(INTEL_CE_GBE_MDIC_GO));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
			writel(mdic, E1000_MDIO_CMD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
			/* Poll the ready bit to see if the MDI read
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
			 * completed
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
			for (i = 0; i < 64; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
				udelay(50);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
				mdic = readl(E1000_MDIO_CMD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
				if (!(mdic & INTEL_CE_GBE_MDIC_GO))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
					break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
			if (mdic & INTEL_CE_GBE_MDIC_GO) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
				e_dbg("MDI Read did not complete\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
				return -E1000_ERR_PHY;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
			mdic = readl(E1000_MDIO_STS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
			if (mdic & INTEL_CE_GBE_MDIC_READ_ERROR) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
				e_dbg("MDI Read Error\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
				return -E1000_ERR_PHY;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
			*phy_data = (u16) mdic;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
			mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
				(E1000_MDIC_OP_READ));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
			ew32(MDIC, mdic);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
			/* Poll the ready bit to see if the MDI read
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
			 * completed
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
			for (i = 0; i < 64; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
				udelay(50);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
				mdic = er32(MDIC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
				if (mdic & E1000_MDIC_READY)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
					break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
			if (!(mdic & E1000_MDIC_READY)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
				e_dbg("MDI Read did not complete\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
				return -E1000_ERR_PHY;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
			if (mdic & E1000_MDIC_ERROR) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
				e_dbg("MDI Error\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
				return -E1000_ERR_PHY;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
			*phy_data = (u16) mdic;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		/* We must first send a preamble through the MDIO pin to signal the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		 * beginning of an MII instruction.  This is done by sending 32
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		 * consecutive "1" bits.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
		/* Now combine the next few fields that are required for a read
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
		 * operation.  We use this method instead of calling the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
		 * e1000_shift_out_mdi_bits routine five different times. The format of
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
		 * a MII read instruction consists of a shift out of 14 bits and is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		 * defined as follows:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		 *    <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		 * followed by a shift in of 18 bits.  This first two bits shifted in
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		 * are TurnAround bits used to avoid contention on the MDIO pin when a
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		 * READ operation is performed.  These two bits are thrown away
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		 * followed by a shift in of 16 bits which contains the desired data.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
		mdic = ((reg_addr) | (phy_addr << 5) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
			(PHY_OP_READ << 10) | (PHY_SOF << 12));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
		e1000_shift_out_mdi_bits(hw, mdic, 14);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
		/* Now that we've shifted out the read command to the MII, we need to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
		 * "shift in" the 16-bit value (18 total bits) of the requested PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		 * register address.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		*phy_data = e1000_shift_in_mdi_bits(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
 * e1000_write_phy_reg - write a phy register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
 * @reg_addr: address of the PHY register to write
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
 * @data: data to write to the PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
 * Writes a value to a PHY register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
	u32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
	e_dbg("e1000_write_phy_reg");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
	if ((hw->phy_type == e1000_phy_igp) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
						 (u16) reg_addr);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
					 phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
	return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
				  u16 phy_data)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
	u32 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
	u32 mdic = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
	const u32 phy_addr = (hw->mac_type == e1000_ce4100) ? hw->phy_addr : 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
	e_dbg("e1000_write_phy_reg_ex");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
		e_dbg("PHY Address %d is out of range\n", reg_addr);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
		return -E1000_ERR_PARAM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	if (hw->mac_type > e1000_82543) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
		/* Set up Op-code, Phy Address, register address, and data
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
		 * intended for the PHY register in the MDI Control register.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
		 * The MAC will take care of interfacing with the PHY to send
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
		 * the desired data.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
		if (hw->mac_type == e1000_ce4100) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
			mdic = (((u32) phy_data) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
				(reg_addr << E1000_MDIC_REG_SHIFT) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
				(INTEL_CE_GBE_MDIC_OP_WRITE) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
				(INTEL_CE_GBE_MDIC_GO));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
			writel(mdic, E1000_MDIO_CMD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
			/* Poll the ready bit to see if the MDI read
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
			 * completed
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
			for (i = 0; i < 640; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
				udelay(5);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
				mdic = readl(E1000_MDIO_CMD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
				if (!(mdic & INTEL_CE_GBE_MDIC_GO))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
					break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
			if (mdic & INTEL_CE_GBE_MDIC_GO) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
				e_dbg("MDI Write did not complete\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
				return -E1000_ERR_PHY;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
			mdic = (((u32) phy_data) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
				(reg_addr << E1000_MDIC_REG_SHIFT) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
				(E1000_MDIC_OP_WRITE));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
			ew32(MDIC, mdic);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
			/* Poll the ready bit to see if the MDI read
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
			 * completed
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
			for (i = 0; i < 641; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
				udelay(5);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
				mdic = er32(MDIC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
				if (mdic & E1000_MDIC_READY)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
					break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
			if (!(mdic & E1000_MDIC_READY)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
				e_dbg("MDI Write did not complete\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
				return -E1000_ERR_PHY;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
		/* We'll need to use the SW defined pins to shift the write command
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		 * out to the PHY. We first send a preamble to the PHY to signal the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		 * beginning of the MII instruction.  This is done by sending 32
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
		 * consecutive "1" bits.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
		/* Now combine the remaining required fields that will indicate a
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
		 * write operation. We use this method instead of calling the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
		 * e1000_shift_out_mdi_bits routine for each field in the command. The
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
		 * format of a MII write instruction is as follows:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		 * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
		mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
			(PHY_OP_WRITE << 12) | (PHY_SOF << 14));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		mdic <<= 16;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
		mdic |= (u32) phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
		e1000_shift_out_mdi_bits(hw, mdic, 32);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
 * e1000_phy_hw_reset - reset the phy, hardware style
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
 * Returns the PHY to the power-on reset state
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
s32 e1000_phy_hw_reset(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	u32 ctrl, ctrl_ext;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	u32 led_ctrl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	e_dbg("e1000_phy_hw_reset");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	e_dbg("Resetting Phy...\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	if (hw->mac_type > e1000_82543) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
		/* Read the device control register and assert the E1000_CTRL_PHY_RST
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
		 * bit. Then, take it out of reset.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
		 * For e1000 hardware, we delay for 10ms between the assert
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
		 * and deassert.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
		ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
		ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
		msleep(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
		/* Read the Extended Device Control Register, assert the PHY_RESET_DIR
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
		 * bit to put the PHY into reset. Then, take it out of reset.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		ctrl_ext = er32(CTRL_EXT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
		ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
		ew32(CTRL_EXT, ctrl_ext);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
		msleep(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
		ew32(CTRL_EXT, ctrl_ext);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	udelay(150);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
		/* Configure activity LED after PHY reset */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
		led_ctrl = er32(LEDCTL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
		ew32(LEDCTL, led_ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
	/* Wait for FW to finish PHY configuration. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
	return e1000_get_phy_cfg_done(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
 * e1000_phy_reset - reset the phy to commit settings
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
 * Resets the PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
 * Sets bit 15 of the MII Control register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
s32 e1000_phy_reset(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
	e_dbg("e1000_phy_reset");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
	switch (hw->phy_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	case e1000_phy_igp:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
		ret_val = e1000_phy_hw_reset(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
		ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		phy_data |= MII_CR_RESET;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
		ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
		udelay(1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
	if (hw->phy_type == e1000_phy_igp)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
		e1000_phy_init_script(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
 * e1000_detect_gig_phy - check the phy type
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
 * Probes the expected PHY address for known PHY IDs
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
static s32 e1000_detect_gig_phy(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
	s32 phy_init_status, ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	u16 phy_id_high, phy_id_low;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	bool match = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	e_dbg("e1000_detect_gig_phy");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	if (hw->phy_id != 0)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	/* Read the PHY ID Registers to identify which PHY is onboard. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	hw->phy_id = (u32) (phy_id_high << 16);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	udelay(20);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	hw->phy_id |= (u32) (phy_id_low & PHY_REVISION_MASK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	hw->phy_revision = (u32) phy_id_low & ~PHY_REVISION_MASK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	case e1000_82543:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
		if (hw->phy_id == M88E1000_E_PHY_ID)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
			match = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	case e1000_82544:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
		if (hw->phy_id == M88E1000_I_PHY_ID)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
			match = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	case e1000_82540:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	case e1000_82545:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	case e1000_82545_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	case e1000_82546:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	case e1000_82546_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
		if (hw->phy_id == M88E1011_I_PHY_ID)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
			match = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	case e1000_ce4100:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
		if ((hw->phy_id == RTL8211B_PHY_ID) ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
		    (hw->phy_id == RTL8201N_PHY_ID) ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		    (hw->phy_id == M88E1118_E_PHY_ID))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
			match = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	case e1000_82541:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	case e1000_82541_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
	case e1000_82547:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
	case e1000_82547_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
		if (hw->phy_id == IGP01E1000_I_PHY_ID)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
			match = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
		e_dbg("Invalid MAC type %d\n", hw->mac_type);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
		return -E1000_ERR_CONFIG;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	phy_init_status = e1000_set_phy_type(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	if ((match) && (phy_init_status == E1000_SUCCESS)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
		e_dbg("PHY ID 0x%X detected\n", hw->phy_id);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	e_dbg("Invalid PHY ID 0x%X\n", hw->phy_id);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	return -E1000_ERR_PHY;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
 * e1000_phy_reset_dsp - reset DSP
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
 * Resets the PHY's DSP
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	e_dbg("e1000_phy_reset_dsp");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
	do {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
		ret_val = e1000_write_phy_reg(hw, 29, 0x001d);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
		ret_val = e1000_write_phy_reg(hw, 30, 0x00c1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
		ret_val = e1000_write_phy_reg(hw, 30, 0x0000);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
		ret_val = E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	} while (0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
 * e1000_phy_igp_get_info - get igp specific registers
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
 * @phy_info: PHY information structure
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
 * Get PHY information from various PHY registers for igp PHY only.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
				  struct e1000_phy_info *phy_info)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	u16 phy_data, min_length, max_length, average;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
	e1000_rev_polarity polarity;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	e_dbg("e1000_phy_igp_get_info");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	/* The downshift status is checked only once, after link is established,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	 * and it stored in the hw->speed_downgraded parameter. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	phy_info->downshift = (e1000_downshift) hw->speed_downgraded;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	/* IGP01E1000 does not need to support it. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	/* IGP01E1000 always correct polarity reversal */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	phy_info->polarity_correction = e1000_polarity_reversal_enabled;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	/* Check polarity status */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	ret_val = e1000_check_polarity(hw, &polarity);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	phy_info->cable_polarity = polarity;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
	phy_info->mdix_mode =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
	    (e1000_auto_x_mode) ((phy_data & IGP01E1000_PSSR_MDIX) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
				 IGP01E1000_PSSR_MDIX_SHIFT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
		/* Local/Remote Receiver Information are only valid at 1000 Mbps */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
		phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
		/* Get cable length */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
		ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
		/* Translate to old method */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
		average = (max_length + min_length) / 2;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
		if (average <= e1000_igp_cable_length_50)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
			phy_info->cable_length = e1000_cable_length_50;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
		else if (average <= e1000_igp_cable_length_80)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
			phy_info->cable_length = e1000_cable_length_50_80;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
		else if (average <= e1000_igp_cable_length_110)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
			phy_info->cable_length = e1000_cable_length_80_110;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		else if (average <= e1000_igp_cable_length_140)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
			phy_info->cable_length = e1000_cable_length_110_140;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
		else
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
			phy_info->cable_length = e1000_cable_length_140;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
 * e1000_phy_m88_get_info - get m88 specific registers
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
 * @phy_info: PHY information structure
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
 * Get PHY information from various PHY registers for m88 PHY only.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
				  struct e1000_phy_info *phy_info)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
	e1000_rev_polarity polarity;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	e_dbg("e1000_phy_m88_get_info");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	/* The downshift status is checked only once, after link is established,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
	 * and it stored in the hw->speed_downgraded parameter. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
	phy_info->downshift = (e1000_downshift) hw->speed_downgraded;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
	phy_info->extended_10bt_distance =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
	    ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	     M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	    e1000_10bt_ext_dist_enable_lower :
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	    e1000_10bt_ext_dist_enable_normal;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	phy_info->polarity_correction =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	    ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	     M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	    e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	/* Check polarity status */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	ret_val = e1000_check_polarity(hw, &polarity);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	phy_info->cable_polarity = polarity;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
	phy_info->mdix_mode =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	    (e1000_auto_x_mode) ((phy_data & M88E1000_PSSR_MDIX) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
				 M88E1000_PSSR_MDIX_SHIFT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
		/* Cable Length Estimation and Local/Remote Receiver Information
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
		 * are only valid at 1000 Mbps.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
		phy_info->cable_length =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
		    (e1000_cable_length) ((phy_data &
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
					   M88E1000_PSSR_CABLE_LENGTH) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
					  M88E1000_PSSR_CABLE_LENGTH_SHIFT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
 * e1000_phy_get_info - request phy info
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
 * @phy_info: PHY information structure
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
 * Get PHY information from various PHY registers
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
s32 e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	e_dbg("e1000_phy_get_info");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	phy_info->cable_length = e1000_cable_length_undefined;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
	phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	phy_info->cable_polarity = e1000_rev_polarity_undefined;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
	phy_info->downshift = e1000_downshift_undefined;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	phy_info->polarity_correction = e1000_polarity_reversal_undefined;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	phy_info->mdix_mode = e1000_auto_x_mode_undefined;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	phy_info->local_rx = e1000_1000t_rx_status_undefined;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	phy_info->remote_rx = e1000_1000t_rx_status_undefined;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	if (hw->media_type != e1000_media_type_copper) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
		e_dbg("PHY info is only valid for copper media\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		return -E1000_ERR_CONFIG;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
	ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	if ((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
		e_dbg("PHY info is only valid if link is up\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		return -E1000_ERR_CONFIG;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
	if (hw->phy_type == e1000_phy_igp)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		return e1000_phy_igp_get_info(hw, phy_info);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	else if ((hw->phy_type == e1000_phy_8211) ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
	         (hw->phy_type == e1000_phy_8201))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
	else
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
		return e1000_phy_m88_get_info(hw, phy_info);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
s32 e1000_validate_mdi_setting(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
	e_dbg("e1000_validate_mdi_settings");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	if (!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
		e_dbg("Invalid MDI setting detected\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
		hw->mdix = 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
		return -E1000_ERR_CONFIG;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
 * e1000_init_eeprom_params - initialize sw eeprom vars
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
 * Sets up eeprom variables in the hw struct.  Must be called after mac_type
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
 * is configured.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
s32 e1000_init_eeprom_params(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	u32 eecd = er32(EECD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	s32 ret_val = E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	u16 eeprom_size;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
	e_dbg("e1000_init_eeprom_params");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
	case e1000_82542_rev2_0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
	case e1000_82542_rev2_1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
	case e1000_82543:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
	case e1000_82544:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
		eeprom->type = e1000_eeprom_microwire;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
		eeprom->word_size = 64;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
		eeprom->opcode_bits = 3;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
		eeprom->address_bits = 6;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
		eeprom->delay_usec = 50;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
	case e1000_82540:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
	case e1000_82545:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
	case e1000_82545_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
	case e1000_82546:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	case e1000_82546_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
		eeprom->type = e1000_eeprom_microwire;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
		eeprom->opcode_bits = 3;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
		eeprom->delay_usec = 50;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
		if (eecd & E1000_EECD_SIZE) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
			eeprom->word_size = 256;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
			eeprom->address_bits = 8;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
			eeprom->word_size = 64;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
			eeprom->address_bits = 6;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
	case e1000_82541:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
	case e1000_82541_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
	case e1000_82547:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	case e1000_82547_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
		if (eecd & E1000_EECD_TYPE) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
			eeprom->type = e1000_eeprom_spi;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
			eeprom->opcode_bits = 8;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
			eeprom->delay_usec = 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
			if (eecd & E1000_EECD_ADDR_BITS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
				eeprom->page_size = 32;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
				eeprom->address_bits = 16;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
			} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
				eeprom->page_size = 8;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
				eeprom->address_bits = 8;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
			eeprom->type = e1000_eeprom_microwire;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
			eeprom->opcode_bits = 3;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
			eeprom->delay_usec = 50;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
			if (eecd & E1000_EECD_ADDR_BITS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
				eeprom->word_size = 256;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
				eeprom->address_bits = 8;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
			} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
				eeprom->word_size = 64;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
				eeprom->address_bits = 6;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
	if (eeprom->type == e1000_eeprom_spi) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
		/* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
		 * 32KB (incremented by powers of 2).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
		/* Set to default value for initial eeprom read. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		eeprom->word_size = 64;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
		eeprom_size =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
		    (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
		/* 256B eeprom size was not supported in earlier hardware, so we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
		 * bump eeprom_size up one to ensure that "1" (which maps to 256B)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
		 * is never the result used in the shifting logic below. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
		if (eeprom_size)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
			eeprom_size++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
		eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
	return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
 * e1000_raise_ee_clk - Raises the EEPROM's clock input.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
 * @eecd: EECD's current value
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
	/* Raise the clock input to the EEPROM (by setting the SK bit), and then
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
	 * wait <delay> microseconds.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	*eecd = *eecd | E1000_EECD_SK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	ew32(EECD, *eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
	E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	udelay(hw->eeprom.delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
 * e1000_lower_ee_clk - Lowers the EEPROM's clock input.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
 * @eecd: EECD's current value
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
	 * wait 50 microseconds.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
	*eecd = *eecd & ~E1000_EECD_SK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	ew32(EECD, *eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
	udelay(hw->eeprom.delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
 * e1000_shift_out_ee_bits - Shift data bits out to the EEPROM.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
 * @data: data to send to the EEPROM
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
 * @count: number of bits to shift out
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data, u16 count)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
	u32 eecd;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	u32 mask;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	/* We need to shift "count" bits out to the EEPROM. So, value in the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	 * "data" parameter will be shifted out to the EEPROM one bit at a time.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	 * In order to do this, "data" must be broken down into bits.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
	mask = 0x01 << (count - 1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	eecd = er32(EECD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	if (eeprom->type == e1000_eeprom_microwire) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
		eecd &= ~E1000_EECD_DO;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	} else if (eeprom->type == e1000_eeprom_spi) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
		eecd |= E1000_EECD_DO;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	do {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
		 * and then raising and then lowering the clock (the SK bit controls
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
		 * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
		 * by setting "DI" to "0" and then raising and then lowering the clock.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
		eecd &= ~E1000_EECD_DI;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
		if (data & mask)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
			eecd |= E1000_EECD_DI;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
		udelay(eeprom->delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
		e1000_raise_ee_clk(hw, &eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
		e1000_lower_ee_clk(hw, &eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
		mask = mask >> 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
	} while (mask);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
	/* We leave the "DI" bit set to "0" when we leave this routine. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
	eecd &= ~E1000_EECD_DI;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
	ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
 * e1000_shift_in_ee_bits - Shift data bits in from the EEPROM
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
 * @count: number of bits to shift in
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	u32 eecd;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
	u32 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
	u16 data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
	/* In order to read a register from the EEPROM, we need to shift 'count'
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
	 * bits in from the EEPROM. Bits are "shifted in" by raising the clock
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
	 * input to the EEPROM (setting the SK bit), and then reading the value of
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
	 * the "DO" bit.  During this "shifting in" process the "DI" bit should
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
	 * always be clear.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
	eecd = er32(EECD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
	data = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
	for (i = 0; i < count; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
		data = data << 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
		e1000_raise_ee_clk(hw, &eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
		eecd = er32(EECD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
		eecd &= ~(E1000_EECD_DI);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
		if (eecd & E1000_EECD_DO)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
			data |= 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
		e1000_lower_ee_clk(hw, &eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
	return data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
 * e1000_acquire_eeprom - Prepares EEPROM for access
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
 * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
 * function should be called before issuing a command to the EEPROM.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
static s32 e1000_acquire_eeprom(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
	u32 eecd, i = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
	e_dbg("e1000_acquire_eeprom");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
	eecd = er32(EECD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	/* Request EEPROM Access */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
	if (hw->mac_type > e1000_82544) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
		eecd |= E1000_EECD_REQ;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
		eecd = er32(EECD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
		while ((!(eecd & E1000_EECD_GNT)) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
		       (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
			i++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
			udelay(5);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
			eecd = er32(EECD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
		if (!(eecd & E1000_EECD_GNT)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
			eecd &= ~E1000_EECD_REQ;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
			ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
			e_dbg("Could not acquire EEPROM grant\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
			return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
	/* Setup EEPROM for Read/Write */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	if (eeprom->type == e1000_eeprom_microwire) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
		/* Clear SK and DI */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		/* Set CS */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
		eecd |= E1000_EECD_CS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
	} else if (eeprom->type == e1000_eeprom_spi) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
		/* Clear SK and CS */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
		udelay(1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
 * e1000_standby_eeprom - Returns EEPROM to a "standby" state
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
static void e1000_standby_eeprom(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
	u32 eecd;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	eecd = er32(EECD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
	if (eeprom->type == e1000_eeprom_microwire) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
		udelay(eeprom->delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
		/* Clock high */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
		eecd |= E1000_EECD_SK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
		udelay(eeprom->delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
		/* Select EEPROM */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
		eecd |= E1000_EECD_CS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
		udelay(eeprom->delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
		/* Clock low */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
		eecd &= ~E1000_EECD_SK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		udelay(eeprom->delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	} else if (eeprom->type == e1000_eeprom_spi) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
		/* Toggle CS to flush commands */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
		eecd |= E1000_EECD_CS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
		udelay(eeprom->delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
		eecd &= ~E1000_EECD_CS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
		udelay(eeprom->delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
 * e1000_release_eeprom - drop chip select
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
 * Terminates a command by inverting the EEPROM's chip select pin
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
static void e1000_release_eeprom(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
	u32 eecd;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
	e_dbg("e1000_release_eeprom");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
	eecd = er32(EECD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
	if (hw->eeprom.type == e1000_eeprom_spi) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
		eecd |= E1000_EECD_CS;	/* Pull CS high */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
		eecd &= ~E1000_EECD_SK;	/* Lower SCK */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
		udelay(hw->eeprom.delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
	} else if (hw->eeprom.type == e1000_eeprom_microwire) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
		/* cleanup eeprom */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
		/* CS on Microwire is active-high */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
		/* Rising edge of clock */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
		eecd |= E1000_EECD_SK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
		udelay(hw->eeprom.delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
		/* Falling edge of clock */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
		eecd &= ~E1000_EECD_SK;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
		udelay(hw->eeprom.delay_usec);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
	/* Stop requesting EEPROM access */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
	if (hw->mac_type > e1000_82544) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
		eecd &= ~E1000_EECD_REQ;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
		ew32(EECD, eecd);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
 * e1000_spi_eeprom_ready - Reads a 16 bit word from the EEPROM.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
	u16 retry_count = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
	u8 spi_stat_reg;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
	e_dbg("e1000_spi_eeprom_ready");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	/* Read "Status Register" repeatedly until the LSB is cleared.  The
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
	 * EEPROM will signal that the command has been completed by clearing
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	 * bit 0 of the internal status register.  If it's not cleared within
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
	 * 5 milliseconds, then error out.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
	retry_count = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
	do {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
		e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
					hw->eeprom.opcode_bits);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
		spi_stat_reg = (u8) e1000_shift_in_ee_bits(hw, 8);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
		if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
		udelay(5);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
		retry_count += 5;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
		e1000_standby_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
	} while (retry_count < EEPROM_MAX_RETRY_SPI);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
	/* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
	 * only 0-5mSec on 5V devices)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	if (retry_count >= EEPROM_MAX_RETRY_SPI) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
		e_dbg("SPI EEPROM Status error\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
		return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
 * e1000_read_eeprom - Reads a 16 bit word from the EEPROM.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
 * @offset: offset of  word in the EEPROM to read
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
 * @data: word read from the EEPROM
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
 * @words: number of words to read
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
	s32 ret;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
	spin_lock(&e1000_eeprom_lock);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
	ret = e1000_do_read_eeprom(hw, offset, words, data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
	spin_unlock(&e1000_eeprom_lock);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
	return ret;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
				u16 *data)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
	u32 i = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
	e_dbg("e1000_read_eeprom");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
	if (hw->mac_type == e1000_ce4100) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
		GBE_CONFIG_FLASH_READ(GBE_CONFIG_BASE_VIRT, offset, words,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
		                      data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
	/* If eeprom is not yet detected, do so now */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
	if (eeprom->word_size == 0)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
		e1000_init_eeprom_params(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
	/* A check for invalid values:  offset too large, too many words, and not
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
	 * enough words.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
	if ((offset >= eeprom->word_size)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	    || (words > eeprom->word_size - offset) || (words == 0)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
		e_dbg("\"words\" parameter out of bounds. Words = %d,"
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
		      "size = %d\n", offset, eeprom->word_size);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
		return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
	/* EEPROM's that don't use EERD to read require us to bit-bang the SPI
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
	 * directly. In this case, we need to acquire the EEPROM so that
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	 * FW or other port software does not interrupt.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	/* Prepare the EEPROM for bit-bang reading */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
		return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
	/* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
	 * acquired the EEPROM at this point, so any returns should release it */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
	if (eeprom->type == e1000_eeprom_spi) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
		u16 word_in;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
		u8 read_opcode = EEPROM_READ_OPCODE_SPI;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
		if (e1000_spi_eeprom_ready(hw)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
			e1000_release_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
			return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
		e1000_standby_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
		/* Some SPI eeproms use the 8th address bit embedded in the opcode */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
		if ((eeprom->address_bits == 8) && (offset >= 128))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
			read_opcode |= EEPROM_A8_OPCODE_SPI;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
		/* Send the READ command (opcode + addr)  */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
		e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
		e1000_shift_out_ee_bits(hw, (u16) (offset * 2),
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
					eeprom->address_bits);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
		/* Read the data.  The address of the eeprom internally increments with
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
		 * each byte (spi) being read, saving on the overhead of eeprom setup
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
		 * and tear-down.  The address counter will roll over if reading beyond
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		 * the size of the eeprom, thus allowing the entire memory to be read
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
		 * starting from any offset. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
		for (i = 0; i < words; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
			word_in = e1000_shift_in_ee_bits(hw, 16);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
			data[i] = (word_in >> 8) | (word_in << 8);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
	} else if (eeprom->type == e1000_eeprom_microwire) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
		for (i = 0; i < words; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
			/* Send the READ command (opcode + addr)  */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
			e1000_shift_out_ee_bits(hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
						EEPROM_READ_OPCODE_MICROWIRE,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
						eeprom->opcode_bits);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
			e1000_shift_out_ee_bits(hw, (u16) (offset + i),
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
						eeprom->address_bits);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
			/* Read the data.  For microwire, each word requires the overhead
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
			 * of eeprom setup and tear-down. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
			data[i] = e1000_shift_in_ee_bits(hw, 16);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
			e1000_standby_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
	/* End this read operation */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
	e1000_release_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
 * e1000_validate_eeprom_checksum - Verifies that the EEPROM has a valid checksum
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
 * Reads the first 64 16 bit words of the EEPROM and sums the values read.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
 * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
 * valid.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
	u16 checksum = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
	u16 i, eeprom_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
	e_dbg("e1000_validate_eeprom_checksum");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
		if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
			e_dbg("EEPROM Read Error\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
			return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
		checksum += eeprom_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
#ifdef CONFIG_PARISC
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
	/* This is a signature and not a checksum on HP c8000 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
	if ((hw->subsystem_vendor_id == 0x103C) && (eeprom_data == 0x16d6))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
#endif
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
	if (checksum == (u16) EEPROM_SUM)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
	else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
		e_dbg("EEPROM Checksum Invalid\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
		return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
 * e1000_update_eeprom_checksum - Calculates/writes the EEPROM checksum
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
 * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
 * Writes the difference to word offset 63 of the EEPROM.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
s32 e1000_update_eeprom_checksum(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
	u16 checksum = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
	u16 i, eeprom_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
	e_dbg("e1000_update_eeprom_checksum");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
	for (i = 0; i < EEPROM_CHECKSUM_REG; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
		if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
			e_dbg("EEPROM Read Error\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
			return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
		checksum += eeprom_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
	checksum = (u16) EEPROM_SUM - checksum;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
	if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
		e_dbg("EEPROM Write Error\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
		return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
 * e1000_write_eeprom - write words to the different EEPROM types.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
 * @offset: offset within the EEPROM to be written to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
 * @words: number of words to write
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
 * @data: 16 bit word to be written to the EEPROM
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
 * If e1000_update_eeprom_checksum is not called after this function, the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
 * EEPROM will most likely contain an invalid checksum.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
	s32 ret;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
	spin_lock(&e1000_eeprom_lock);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
	ret = e1000_do_write_eeprom(hw, offset, words, data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
	spin_unlock(&e1000_eeprom_lock);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
	return ret;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
				 u16 *data)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	s32 status = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	e_dbg("e1000_write_eeprom");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	if (hw->mac_type == e1000_ce4100) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
		GBE_CONFIG_FLASH_WRITE(GBE_CONFIG_BASE_VIRT, offset, words,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
		                       data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	/* If eeprom is not yet detected, do so now */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
	if (eeprom->word_size == 0)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
		e1000_init_eeprom_params(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
	/* A check for invalid values:  offset too large, too many words, and not
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
	 * enough words.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
	if ((offset >= eeprom->word_size)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
	    || (words > eeprom->word_size - offset) || (words == 0)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
		e_dbg("\"words\" parameter out of bounds\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
		return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
	/* Prepare the EEPROM for writing  */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
		return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
	if (eeprom->type == e1000_eeprom_microwire) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
		status = e1000_write_eeprom_microwire(hw, offset, words, data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
		status = e1000_write_eeprom_spi(hw, offset, words, data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
		msleep(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
	/* Done with writing */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
	e1000_release_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
	return status;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
 * e1000_write_eeprom_spi - Writes a 16 bit word to a given offset in an SPI EEPROM.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
 * @offset: offset within the EEPROM to be written to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
 * @words: number of words to write
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
 * @data: pointer to array of 8 bit words to be written to the EEPROM
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset, u16 words,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
				  u16 *data)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
	u16 widx = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
	e_dbg("e1000_write_eeprom_spi");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
	while (widx < words) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
		u8 write_opcode = EEPROM_WRITE_OPCODE_SPI;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
		if (e1000_spi_eeprom_ready(hw))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
			return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
		e1000_standby_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
		/*  Send the WRITE ENABLE command (8 bit opcode )  */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
		e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
					eeprom->opcode_bits);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
		e1000_standby_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
		/* Some SPI eeproms use the 8th address bit embedded in the opcode */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
		if ((eeprom->address_bits == 8) && (offset >= 128))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
			write_opcode |= EEPROM_A8_OPCODE_SPI;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
		/* Send the Write command (8-bit opcode + addr) */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
		e1000_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
		e1000_shift_out_ee_bits(hw, (u16) ((offset + widx) * 2),
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
					eeprom->address_bits);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		/* Send the data */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
		/* Loop to allow for up to whole page write (32 bytes) of eeprom */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
		while (widx < words) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
			u16 word_out = data[widx];
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
			word_out = (word_out >> 8) | (word_out << 8);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
			e1000_shift_out_ee_bits(hw, word_out, 16);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
			widx++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
			/* Some larger eeprom sizes are capable of a 32-byte PAGE WRITE
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
			 * operation, while the smaller eeproms are capable of an 8-byte
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
			 * PAGE WRITE operation.  Break the inner loop to pass new address
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
			 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
			if ((((offset + widx) * 2) % eeprom->page_size) == 0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
				e1000_standby_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
				break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
 * e1000_write_eeprom_microwire - Writes a 16 bit word to a given offset in a Microwire EEPROM.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
 * @offset: offset within the EEPROM to be written to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
 * @words: number of words to write
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
 * @data: pointer to array of 8 bit words to be written to the EEPROM
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
					u16 words, u16 *data)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
	u32 eecd;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
	u16 words_written = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
	u16 i = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
	e_dbg("e1000_write_eeprom_microwire");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
	/* Send the write enable command to the EEPROM (3-bit opcode plus
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
	 * 6/8-bit dummy address beginning with 11).  It's less work to include
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
	 * the 11 of the dummy address as part of the opcode than it is to shift
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
	 * it over the correct number of bits for the address.  This puts the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
	 * EEPROM into write/erase mode.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
	e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
				(u16) (eeprom->opcode_bits + 2));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	/* Prepare the EEPROM */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	e1000_standby_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	while (words_written < words) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
		/* Send the Write command (3-bit opcode + addr) */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
		e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
					eeprom->opcode_bits);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
		e1000_shift_out_ee_bits(hw, (u16) (offset + words_written),
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
					eeprom->address_bits);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
		/* Send the data */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
		e1000_shift_out_ee_bits(hw, data[words_written], 16);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
		/* Toggle the CS line.  This in effect tells the EEPROM to execute
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
		 * the previous command.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
		e1000_standby_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
		/* Read DO repeatedly until it is high (equal to '1').  The EEPROM will
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
		 * signal that the command has been completed by raising the DO signal.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
		 * If DO does not go high in 10 milliseconds, then error out.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
		for (i = 0; i < 200; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
			eecd = er32(EECD);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
			if (eecd & E1000_EECD_DO)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
				break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
			udelay(50);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
		if (i == 200) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
			e_dbg("EEPROM Write did not complete\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
			return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
		/* Recover from write */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
		e1000_standby_eeprom(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
		words_written++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	/* Send the write disable command to the EEPROM (3-bit opcode plus
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
	 * 6/8-bit dummy address beginning with 10).  It's less work to include
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	 * the 10 of the dummy address as part of the opcode than it is to shift
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
	 * it over the correct number of bits for the address.  This takes the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	 * EEPROM out of write/erase mode.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
	e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
				(u16) (eeprom->opcode_bits + 2));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
 * e1000_read_mac_addr - read the adapters MAC from eeprom
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
 * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
 * second function of dual function devices
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
s32 e1000_read_mac_addr(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
	u16 offset;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
	u16 eeprom_data, i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
	e_dbg("e1000_read_mac_addr");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
	for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
		offset = i >> 1;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
		if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
			e_dbg("EEPROM Read Error\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
			return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
		hw->perm_mac_addr[i] = (u8) (eeprom_data & 0x00FF);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		hw->perm_mac_addr[i + 1] = (u8) (eeprom_data >> 8);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
	case e1000_82546:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
	case e1000_82546_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
			hw->perm_mac_addr[5] ^= 0x01;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	for (i = 0; i < NODE_ADDRESS_SIZE; i++)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
		hw->mac_addr[i] = hw->perm_mac_addr[i];
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
 * e1000_init_rx_addrs - Initializes receive address filters.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
 * Places the MAC address in receive address register 0 and clears the rest
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
 * of the receive address registers. Clears the multicast table. Assumes
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
 * the receiver is in reset when the routine is called.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
static void e1000_init_rx_addrs(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
	u32 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
	u32 rar_num;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
	e_dbg("e1000_init_rx_addrs");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	/* Setup the receive address. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
	e_dbg("Programming MAC Address into RAR[0]\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
	e1000_rar_set(hw, hw->mac_addr, 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
	rar_num = E1000_RAR_ENTRIES;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
	/* Zero out the other 15 receive addresses. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
	e_dbg("Clearing RAR[1-15]\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
	for (i = 1; i < rar_num; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
 * e1000_hash_mc_addr - Hashes an address to determine its location in the multicast table
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
 * @mc_addr: the multicast address to hash
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	u32 hash_value = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
	/* The portion of the address that is used for the hash table is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
	 * determined by the mc_filter_type setting.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
	switch (hw->mc_filter_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
		/* [0] [1] [2] [3] [4] [5]
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
		 * 01  AA  00  12  34  56
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
		 * LSB                 MSB
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
	case 0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
		/* [47:36] i.e. 0x563 for above example address */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
		hash_value = ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
	case 1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
		/* [46:35] i.e. 0xAC6 for above example address */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
		hash_value = ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
	case 2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
		/* [45:34] i.e. 0x5D8 for above example address */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
		hash_value = ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
	case 3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
		/* [43:32] i.e. 0x634 for above example address */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
		hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
	hash_value &= 0xFFF;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
	return hash_value;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
 * e1000_rar_set - Puts an ethernet address into a receive address register.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
 * @addr: Address to put into receive address register
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
 * @index: Receive address register to write
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
	u32 rar_low, rar_high;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	/* HW expects these in little endian so we reverse the byte order
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	 * from network order (big endian) to little endian
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
	rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
		   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
	/* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
	 * unit hang.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
	 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
	 * Description:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
	 * If there are any Rx frames queued up or otherwise present in the HW
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
	 * before RSS is enabled, and then we enable RSS, the HW Rx unit will
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
	 * hang.  To work around this issue, we have to disable receives and
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
	 * flush out all Rx frames before we enable RSS. To do so, we modify we
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
	 * redirect all Rx traffic to manageability and then reset the HW.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
	 * This flushes away Rx frames, and (since the redirections to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	 * manageability persists across resets) keeps new ones from coming in
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
	 * while we work.  Then, we clear the Address Valid AV bit for all MAC
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
	 * addresses and undo the re-direction to manageability.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
	 * Now, frames are coming in again, but the MAC won't accept them, so
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
	 * far so good.  We now proceed to initialize RSS (if necessary) and
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
	 * configure the Rx unit.  Last, we re-enable the AV bits and continue
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
	 * on our merry way.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
		/* Indicate to hardware the Address is Valid. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
		rar_high |= E1000_RAH_AV;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
	E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
	E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
	E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
	E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
 * e1000_write_vfta - Writes a value to the specified offset in the VLAN filter table.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
 * @offset: Offset in VLAN filer table to write
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
 * @value: Value to write into VLAN filter table
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
	u32 temp;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
	if ((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
		temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
		E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
 * e1000_clear_vfta - Clears the VLAN filer table
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
static void e1000_clear_vfta(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
	u32 offset;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	u32 vfta_value = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
	u32 vfta_offset = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
	u32 vfta_bit_in_reg = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
		/* If the offset we want to clear is the same offset of the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
		 * manageability VLAN ID, then clear all bits except that of the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		 * manageability unit */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
		E1000_WRITE_FLUSH();
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
static s32 e1000_id_led_init(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
	u32 ledctl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	const u32 ledctl_mask = 0x000000FF;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
	u16 eeprom_data, i, temp;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	const u16 led_mask = 0x0F;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	e_dbg("e1000_id_led_init");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
	if (hw->mac_type < e1000_82540) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
		/* Nothing to do */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
	ledctl = er32(LEDCTL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
	hw->ledctl_default = ledctl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
	hw->ledctl_mode1 = hw->ledctl_default;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
	hw->ledctl_mode2 = hw->ledctl_default;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
	if (e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		e_dbg("EEPROM Read Error\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
		return -E1000_ERR_EEPROM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
	if ((eeprom_data == ID_LED_RESERVED_0000) ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
	    (eeprom_data == ID_LED_RESERVED_FFFF)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
		eeprom_data = ID_LED_DEFAULT;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
	for (i = 0; i < 4; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
		temp = (eeprom_data >> (i << 2)) & led_mask;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
		switch (temp) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
		case ID_LED_ON1_DEF2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
		case ID_LED_ON1_ON2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
		case ID_LED_ON1_OFF2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
			hw->ledctl_mode1 |= ledctl_on << (i << 3);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		case ID_LED_OFF1_DEF2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
		case ID_LED_OFF1_ON2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
		case ID_LED_OFF1_OFF2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
			hw->ledctl_mode1 |= ledctl_off << (i << 3);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
		default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
			/* Do nothing */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
		switch (temp) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
		case ID_LED_DEF1_ON2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		case ID_LED_ON1_ON2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
		case ID_LED_OFF1_ON2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
			hw->ledctl_mode2 |= ledctl_on << (i << 3);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
		case ID_LED_DEF1_OFF2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
		case ID_LED_ON1_OFF2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
		case ID_LED_OFF1_OFF2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
			hw->ledctl_mode2 |= ledctl_off << (i << 3);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
		default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
			/* Do nothing */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
 * e1000_setup_led
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
 * Prepares SW controlable LED for use and saves the current state of the LED.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
s32 e1000_setup_led(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	u32 ledctl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
	s32 ret_val = E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
	e_dbg("e1000_setup_led");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
	case e1000_82542_rev2_0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
	case e1000_82542_rev2_1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
	case e1000_82543:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	case e1000_82544:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
		/* No setup necessary */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
	case e1000_82541:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	case e1000_82547:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
	case e1000_82541_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
	case e1000_82547_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
		/* Turn off PHY Smart Power Down (if enabled) */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
					     &hw->phy_spd_default);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
					      (u16) (hw->phy_spd_default &
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
						     ~IGP01E1000_GMII_SPD));
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
		/* Fall Through */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
		if (hw->media_type == e1000_media_type_fiber) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
			ledctl = er32(LEDCTL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
			/* Save current LEDCTL settings */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
			hw->ledctl_default = ledctl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
			/* Turn off LED0 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
			ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
				    E1000_LEDCTL_LED0_BLINK |
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
				    E1000_LEDCTL_LED0_MODE_MASK);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
			ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
				   E1000_LEDCTL_LED0_MODE_SHIFT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
			ew32(LEDCTL, ledctl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		} else if (hw->media_type == e1000_media_type_copper)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
			ew32(LEDCTL, hw->ledctl_mode1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
 * e1000_cleanup_led - Restores the saved state of the SW controlable LED.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
s32 e1000_cleanup_led(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	s32 ret_val = E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	e_dbg("e1000_cleanup_led");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	case e1000_82542_rev2_0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
	case e1000_82542_rev2_1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
	case e1000_82543:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	case e1000_82544:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
		/* No cleanup necessary */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
	case e1000_82541:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
	case e1000_82547:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
	case e1000_82541_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	case e1000_82547_rev_2:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
		/* Turn on PHY Smart Power Down (if previously enabled) */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
					      hw->phy_spd_default);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
		/* Fall Through */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
		/* Restore LEDCTL settings */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
		ew32(LEDCTL, hw->ledctl_default);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
 * e1000_led_on - Turns on the software controllable LED
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
s32 e1000_led_on(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
	u32 ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
	e_dbg("e1000_led_on");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
	case e1000_82542_rev2_0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
	case e1000_82542_rev2_1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
	case e1000_82543:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
		/* Set SW Defineable Pin 0 to turn on the LED */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
		ctrl |= E1000_CTRL_SWDPIN0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
		ctrl |= E1000_CTRL_SWDPIO0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
	case e1000_82544:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
		if (hw->media_type == e1000_media_type_fiber) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
			/* Set SW Defineable Pin 0 to turn on the LED */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
			ctrl |= E1000_CTRL_SWDPIN0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
			ctrl |= E1000_CTRL_SWDPIO0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
			/* Clear SW Defineable Pin 0 to turn on the LED */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
			ctrl &= ~E1000_CTRL_SWDPIN0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
			ctrl |= E1000_CTRL_SWDPIO0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
		if (hw->media_type == e1000_media_type_fiber) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
			/* Clear SW Defineable Pin 0 to turn on the LED */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
			ctrl &= ~E1000_CTRL_SWDPIN0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
			ctrl |= E1000_CTRL_SWDPIO0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
		} else if (hw->media_type == e1000_media_type_copper) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
			ew32(LEDCTL, hw->ledctl_mode2);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
			return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
 * e1000_led_off - Turns off the software controllable LED
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
s32 e1000_led_off(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
	u32 ctrl = er32(CTRL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
	e_dbg("e1000_led_off");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	case e1000_82542_rev2_0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
	case e1000_82542_rev2_1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
	case e1000_82543:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
		/* Clear SW Defineable Pin 0 to turn off the LED */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
		ctrl &= ~E1000_CTRL_SWDPIN0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
		ctrl |= E1000_CTRL_SWDPIO0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	case e1000_82544:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
		if (hw->media_type == e1000_media_type_fiber) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
			/* Clear SW Defineable Pin 0 to turn off the LED */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
			ctrl &= ~E1000_CTRL_SWDPIN0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
			ctrl |= E1000_CTRL_SWDPIO0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
			/* Set SW Defineable Pin 0 to turn off the LED */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
			ctrl |= E1000_CTRL_SWDPIN0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
			ctrl |= E1000_CTRL_SWDPIO0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
		if (hw->media_type == e1000_media_type_fiber) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
			/* Set SW Defineable Pin 0 to turn off the LED */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
			ctrl |= E1000_CTRL_SWDPIN0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
			ctrl |= E1000_CTRL_SWDPIO0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
		} else if (hw->media_type == e1000_media_type_copper) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
			ew32(LEDCTL, hw->ledctl_mode1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
			return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
	ew32(CTRL, ctrl);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
 * e1000_clear_hw_cntrs - Clears all hardware statistics counters.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
static void e1000_clear_hw_cntrs(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	volatile u32 temp;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	temp = er32(CRCERRS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	temp = er32(SYMERRS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	temp = er32(MPC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	temp = er32(SCC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	temp = er32(ECOL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	temp = er32(MCC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	temp = er32(LATECOL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	temp = er32(COLC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	temp = er32(DC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	temp = er32(SEC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	temp = er32(RLEC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
	temp = er32(XONRXC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	temp = er32(XONTXC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
	temp = er32(XOFFRXC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
	temp = er32(XOFFTXC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
	temp = er32(FCRUC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
	temp = er32(PRC64);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
	temp = er32(PRC127);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
	temp = er32(PRC255);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
	temp = er32(PRC511);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
	temp = er32(PRC1023);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
	temp = er32(PRC1522);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	temp = er32(GPRC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
	temp = er32(BPRC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
	temp = er32(MPRC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
	temp = er32(GPTC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	temp = er32(GORCL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
	temp = er32(GORCH);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	temp = er32(GOTCL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	temp = er32(GOTCH);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
	temp = er32(RNBC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	temp = er32(RUC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
	temp = er32(RFC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
	temp = er32(ROC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
	temp = er32(RJC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
	temp = er32(TORL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
	temp = er32(TORH);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
	temp = er32(TOTL);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
	temp = er32(TOTH);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
	temp = er32(TPR);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
	temp = er32(TPT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
	temp = er32(PTC64);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
	temp = er32(PTC127);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
	temp = er32(PTC255);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
	temp = er32(PTC511);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
	temp = er32(PTC1023);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
	temp = er32(PTC1522);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
	temp = er32(MPTC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
	temp = er32(BPTC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
	if (hw->mac_type < e1000_82543)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
		return;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
	temp = er32(ALGNERRC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
	temp = er32(RXERRC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
	temp = er32(TNCRS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
	temp = er32(CEXTERR);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
	temp = er32(TSCTC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
	temp = er32(TSCTFC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
	if (hw->mac_type <= e1000_82544)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
		return;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
	temp = er32(MGTPRC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
	temp = er32(MGTPDC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	temp = er32(MGTPTC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
 * e1000_reset_adaptive - Resets Adaptive IFS to its default state.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
 * Call this after e1000_init_hw. You may override the IFS defaults by setting
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
 * hw->ifs_params_forced to true. However, you must initialize hw->
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
 * current_ifs_val, ifs_min_val, ifs_max_val, ifs_step_size, and ifs_ratio
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
 * before calling this function.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
void e1000_reset_adaptive(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
	e_dbg("e1000_reset_adaptive");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
	if (hw->adaptive_ifs) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
		if (!hw->ifs_params_forced) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
			hw->current_ifs_val = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
			hw->ifs_min_val = IFS_MIN;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
			hw->ifs_max_val = IFS_MAX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
			hw->ifs_step_size = IFS_STEP;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
			hw->ifs_ratio = IFS_RATIO;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
		hw->in_ifs_mode = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
		ew32(AIT, 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
		e_dbg("Not in Adaptive IFS mode!\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
 * e1000_update_adaptive - update adaptive IFS
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
 * @tx_packets: Number of transmits since last callback
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
 * @total_collisions: Number of collisions since last callback
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
 * Called during the callback/watchdog routine to update IFS value based on
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
 * the ratio of transmits to collisions.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
void e1000_update_adaptive(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
	e_dbg("e1000_update_adaptive");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
	if (hw->adaptive_ifs) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
		if ((hw->collision_delta *hw->ifs_ratio) > hw->tx_packet_delta) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
			if (hw->tx_packet_delta > MIN_NUM_XMITS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
				hw->in_ifs_mode = true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
				if (hw->current_ifs_val < hw->ifs_max_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
					if (hw->current_ifs_val == 0)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
						hw->current_ifs_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
						    hw->ifs_min_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
					else
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
						hw->current_ifs_val +=
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
						    hw->ifs_step_size;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
					ew32(AIT, hw->current_ifs_val);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
				}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
			if (hw->in_ifs_mode
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
			    && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
				hw->current_ifs_val = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
				hw->in_ifs_mode = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
				ew32(AIT, 0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
		e_dbg("Not in Adaptive IFS mode!\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
 * e1000_tbi_adjust_stats
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
 * @frame_len: The length of the frame in question
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
 * @mac_addr: The Ethernet destination address of the frame in question
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
 * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
			    u32 frame_len, u8 *mac_addr)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
	u64 carry_bit;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
	/* First adjust the frame length. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
	frame_len--;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
	/* We need to adjust the statistics counters, since the hardware
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
	 * counters overcount this packet as a CRC error and undercount
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
	 * the packet as a good packet
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
	/* This packet should not be counted as a CRC error.    */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
	stats->crcerrs--;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
	/* This packet does count as a Good Packet Received.    */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
	stats->gprc++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
	/* Adjust the Good Octets received counters             */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
	carry_bit = 0x80000000 & stats->gorcl;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
	stats->gorcl += frame_len;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
	/* If the high bit of Gorcl (the low 32 bits of the Good Octets
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
	 * Received Count) was one before the addition,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
	 * AND it is zero after, then we lost the carry out,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
	 * need to add one to Gorch (Good Octets Received Count High).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
	 * This could be simplified if all environments supported
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
	 * 64-bit integers.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
	if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
		stats->gorch++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
	/* Is this a broadcast or multicast?  Check broadcast first,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
	 * since the test for a multicast frame will test positive on
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
	 * a broadcast frame.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
	if ((mac_addr[0] == (u8) 0xff) && (mac_addr[1] == (u8) 0xff))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
		/* Broadcast packet */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
		stats->bprc++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
	else if (*mac_addr & 0x01)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
		/* Multicast packet */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
		stats->mprc++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
	if (frame_len == hw->max_frame_size) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
		/* In this case, the hardware has overcounted the number of
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
		 * oversize frames.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
		if (stats->roc > 0)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
			stats->roc--;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
	/* Adjust the bin counters when the extra byte put the frame in the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
	 * wrong bin. Remember that the frame_len was adjusted above.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
	 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
	if (frame_len == 64) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
		stats->prc64++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
		stats->prc127--;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
	} else if (frame_len == 127) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
		stats->prc127++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
		stats->prc255--;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
	} else if (frame_len == 255) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
		stats->prc255++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
		stats->prc511--;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
	} else if (frame_len == 511) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
		stats->prc511++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
		stats->prc1023--;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
	} else if (frame_len == 1023) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
		stats->prc1023++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
		stats->prc1522--;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
	} else if (frame_len == 1522) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
		stats->prc1522++;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
 * e1000_get_bus_info
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
 * Gets the current PCI bus type, speed, and width of the hardware
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
void e1000_get_bus_info(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
	u32 status;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
	case e1000_82542_rev2_0:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
	case e1000_82542_rev2_1:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
		hw->bus_type = e1000_bus_type_pci;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
		hw->bus_speed = e1000_bus_speed_unknown;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
		hw->bus_width = e1000_bus_width_unknown;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
		status = er32(STATUS);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
		hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
		    e1000_bus_type_pcix : e1000_bus_type_pci;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
		if (hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
			hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
			    e1000_bus_speed_66 : e1000_bus_speed_120;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
		} else if (hw->bus_type == e1000_bus_type_pci) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
			hw->bus_speed = (status & E1000_STATUS_PCI66) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
			    e1000_bus_speed_66 : e1000_bus_speed_33;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
			switch (status & E1000_STATUS_PCIX_SPEED) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
			case E1000_STATUS_PCIX_SPEED_66:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
				hw->bus_speed = e1000_bus_speed_66;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
				break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
			case E1000_STATUS_PCIX_SPEED_100:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
				hw->bus_speed = e1000_bus_speed_100;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
				break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
			case E1000_STATUS_PCIX_SPEED_133:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
				hw->bus_speed = e1000_bus_speed_133;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
				break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
			default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
				hw->bus_speed = e1000_bus_speed_reserved;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
				break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
		hw->bus_width = (status & E1000_STATUS_BUS64) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
		    e1000_bus_width_64 : e1000_bus_width_32;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
 * e1000_write_reg_io
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
 * @offset: offset to write to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
 * @value: value to write
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
 * Writes a value to one of the devices registers using port I/O (as opposed to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
 * memory mapped I/O). Only 82544 and newer devices support port I/O.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
	unsigned long io_addr = hw->io_base;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
	unsigned long io_data = hw->io_base + 4;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
	e1000_io_write(hw, io_addr, offset);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
	e1000_io_write(hw, io_data, value);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
 * e1000_get_cable_length - Estimates the cable length.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
 * @min_length: The estimated minimum length
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
 * @max_length: The estimated maximum length
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
 * returns: - E1000_ERR_XXX
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
 *            E1000_SUCCESS
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
 * This function always returns a ranged length (minimum & maximum).
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
 * So for M88 phy's, this function interprets the one value returned from the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
 * register to the minimum and maximum range.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
 * For IGP phy's, the function calculates the range by the AGC registers.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
				  u16 *max_length)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
	u16 agc_value = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
	u16 i, phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
	u16 cable_length;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
	e_dbg("e1000_get_cable_length");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
	*min_length = *max_length = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
	/* Use old method for Phy older than IGP */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
	if (hw->phy_type == e1000_phy_m88) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
					     &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
		cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
		    M88E1000_PSSR_CABLE_LENGTH_SHIFT;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
		/* Convert the enum value to ranged values */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
		switch (cable_length) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
		case e1000_cable_length_50:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
			*min_length = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
			*max_length = e1000_igp_cable_length_50;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
		case e1000_cable_length_50_80:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
			*min_length = e1000_igp_cable_length_50;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
			*max_length = e1000_igp_cable_length_80;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
		case e1000_cable_length_80_110:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
			*min_length = e1000_igp_cable_length_80;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
			*max_length = e1000_igp_cable_length_110;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
		case e1000_cable_length_110_140:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
			*min_length = e1000_igp_cable_length_110;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
			*max_length = e1000_igp_cable_length_140;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
		case e1000_cable_length_140:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
			*min_length = e1000_igp_cable_length_140;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
			*max_length = e1000_igp_cable_length_170;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
		default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
			return -E1000_ERR_PHY;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
	} else if (hw->phy_type == e1000_phy_igp) {	/* For IGP PHY */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
		u16 cur_agc_value;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
		u16 min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
		static const u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
		       IGP01E1000_PHY_AGC_A,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
		       IGP01E1000_PHY_AGC_B,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
		       IGP01E1000_PHY_AGC_C,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
		       IGP01E1000_PHY_AGC_D
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
		};
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
		/* Read the AGC registers for all channels */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
		for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
			    e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
			cur_agc_value = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
			/* Value bound check. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
			if ((cur_agc_value >=
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
			     IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
			    || (cur_agc_value == 0))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
				return -E1000_ERR_PHY;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
			agc_value += cur_agc_value;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
			/* Update minimal AGC value. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
			if (min_agc_value > cur_agc_value)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
				min_agc_value = cur_agc_value;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
		/* Remove the minimal AGC result for length < 50m */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
		if (agc_value <
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
		    IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
			agc_value -= min_agc_value;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
			/* Get the average length of the remaining 3 channels */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
			agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
			/* Get the average length of all the 4 channels. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
			agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
		/* Set the range of the calculated length. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
		*min_length = ((e1000_igp_cable_length_table[agc_value] -
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
				IGP01E1000_AGC_RANGE) > 0) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
		    (e1000_igp_cable_length_table[agc_value] -
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
		     IGP01E1000_AGC_RANGE) : 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
		*max_length = e1000_igp_cable_length_table[agc_value] +
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
		    IGP01E1000_AGC_RANGE;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
 * e1000_check_polarity - Check the cable polarity
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
 * @polarity: output parameter : 0 - Polarity is not reversed
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
 *                               1 - Polarity is reversed.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
 * returns: - E1000_ERR_XXX
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
 *            E1000_SUCCESS
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
 * For phy's older than IGP, this function simply reads the polarity bit in the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
 * Phy Status register.  For IGP phy's, this bit is valid only if link speed is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
 * 10 Mbps.  If the link speed is 100 Mbps there is no polarity so this bit will
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
 * return 0.  If the link speed is 1000 Mbps the polarity status is in the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
 * IGP01E1000_PHY_PCS_INIT_REG.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
static s32 e1000_check_polarity(struct e1000_hw *hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
				e1000_rev_polarity *polarity)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
	e_dbg("e1000_check_polarity");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
	if (hw->phy_type == e1000_phy_m88) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
		/* return the Polarity bit in the Status register. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
					     &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
		*polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
			     M88E1000_PSSR_REV_POLARITY_SHIFT) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
		    e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
	} else if (hw->phy_type == e1000_phy_igp) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
		/* Read the Status register to check the speed */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
					     &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
		/* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
		 * find the polarity status */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
		if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
		    IGP01E1000_PSSR_SPEED_1000MBPS) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
			/* Read the GIG initialization PCS register (0x00B4) */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
					       &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
			/* Check the polarity bits */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
			*polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
			    e1000_rev_polarity_reversed :
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
			    e1000_rev_polarity_normal;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
		} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
			/* For 10 Mbps, read the polarity bit in the status register. (for
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
			 * 100 Mbps this bit is always 0) */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
			*polarity =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
			    (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
			    e1000_rev_polarity_reversed :
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
			    e1000_rev_polarity_normal;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
 * e1000_check_downshift - Check if Downshift occurred
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
 * @downshift: output parameter : 0 - No Downshift occurred.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
 *                                1 - Downshift occurred.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
 * returns: - E1000_ERR_XXX
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
 *            E1000_SUCCESS
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
 * For phy's older than IGP, this function reads the Downshift bit in the Phy
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
 * Specific Status register.  For IGP phy's, it reads the Downgrade bit in the
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
 * Link Health register.  In IGP this bit is latched high, so the driver must
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
 * read it immediately after link is established.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
static s32 e1000_check_downshift(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
	e_dbg("e1000_check_downshift");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
	if (hw->phy_type == e1000_phy_igp) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
					     &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
		hw->speed_downgraded =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
		    (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
	} else if (hw->phy_type == e1000_phy_m88) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
					     &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
		hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
		    M88E1000_PSSR_DOWNSHIFT_SHIFT;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
static const u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
	IGP01E1000_PHY_AGC_PARAM_A,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
	IGP01E1000_PHY_AGC_PARAM_B,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
	IGP01E1000_PHY_AGC_PARAM_C,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
	IGP01E1000_PHY_AGC_PARAM_D
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
};
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
static s32 e1000_1000Mb_check_cable_length(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
	u16 min_length, max_length;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
	u16 phy_data, i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
	ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
	if (hw->dsp_config_state != e1000_dsp_config_enabled)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
		return 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
	if (min_length >= e1000_igp_cable_length_50) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
		for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
			ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
						     &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
			phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
			ret_val = e1000_write_phy_reg(hw, dsp_reg_array[i],
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
						      phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
		hw->dsp_config_state = e1000_dsp_config_activated;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
		u16 ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
		u32 idle_errs = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
		/* clear previous idle error counts */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
		for (i = 0; i < ffe_idle_err_timeout; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
			udelay(1000);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
			ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
						     &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
			idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
			if (idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
				hw->ffe_config_state = e1000_ffe_config_active;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
				ret_val = e1000_write_phy_reg(hw,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
					      IGP01E1000_PHY_DSP_FFE,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
					      IGP01E1000_PHY_DSP_FFE_CM_CP);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
				if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
					return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
				break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
			if (idle_errs)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
				ffe_idle_err_timeout =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
					    FFE_IDLE_ERR_COUNT_TIMEOUT_100;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
	return 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
 * e1000_config_dsp_after_link_change
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
 * @link_up: was link up at the time this was called
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
 *            E1000_SUCCESS at any other case.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
 * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
 * gigabit link is achieved to improve link quality.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw, bool link_up)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
	u16 phy_data, phy_saved_data, speed, duplex, i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
	e_dbg("e1000_config_dsp_after_link_change");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
	if (hw->phy_type != e1000_phy_igp)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
	if (link_up) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
		ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
			e_dbg("Error getting link speed and duplex\n");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
		if (speed == SPEED_1000) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
			ret_val = e1000_1000Mb_check_cable_length(hw);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
	} else {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
		if (hw->dsp_config_state == e1000_dsp_config_activated) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
			/* Save off the current value of register 0x2F5B to be restored at
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
			 * the end of the routines. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
			    e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
			/* Disable the PHY transmitter */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
			ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
			msleep(20);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
			ret_val = e1000_write_phy_reg(hw, 0x0000,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
						      IGP01E1000_IEEE_FORCE_GIGA);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
			for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
				ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
				    e1000_read_phy_reg(hw, dsp_reg_array[i],
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
						       &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
				if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
					return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
				phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
				phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
				ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
				    e1000_write_phy_reg(hw, dsp_reg_array[i],
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
							phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
				if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
					return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
			}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
			ret_val = e1000_write_phy_reg(hw, 0x0000,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
						      IGP01E1000_IEEE_RESTART_AUTONEG);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
			msleep(20);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
			/* Now enable the transmitter */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
			    e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
			hw->dsp_config_state = e1000_dsp_config_enabled;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
		if (hw->ffe_config_state == e1000_ffe_config_active) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
			/* Save off the current value of register 0x2F5B to be restored at
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
			 * the end of the routines. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
			    e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
			/* Disable the PHY transmitter */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
			ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
			msleep(20);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
			ret_val = e1000_write_phy_reg(hw, 0x0000,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
						      IGP01E1000_IEEE_FORCE_GIGA);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
						IGP01E1000_PHY_DSP_FFE_DEFAULT);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
			ret_val = e1000_write_phy_reg(hw, 0x0000,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
						      IGP01E1000_IEEE_RESTART_AUTONEG);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
			msleep(20);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
			/* Now enable the transmitter */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
			    e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
			hw->ffe_config_state = e1000_ffe_config_enabled;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
 * e1000_set_phy_mode - Set PHY to class A mode
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
 * Assumes the following operations will follow to enable the new class mode.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
 *  1. Do a PHY soft reset
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
 *  2. Restart auto-negotiation or force link.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
static s32 e1000_set_phy_mode(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
	u16 eeprom_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
	e_dbg("e1000_set_phy_mode");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
	if ((hw->mac_type == e1000_82545_rev_3) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
	    (hw->media_type == e1000_media_type_copper)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
		    e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
				      &eeprom_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
		if (ret_val) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
		if ((eeprom_data != EEPROM_RESERVED_WORD) &&
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
		    (eeprom_data & EEPROM_PHY_CLASS_A)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
			    e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
						0x000B);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
			    e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
						0x8104);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
			hw->phy_reset_disable = false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
 * e1000_set_d3_lplu_state - set d3 link power state
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
 * @active: true to enable lplu false to disable lplu.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
 * This function sets the lplu state according to the active flag.  When
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
 * activating lplu this function also disables smart speed and vise versa.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
 * lplu will not be activated unless the device autonegotiation advertisement
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
 * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
 *            E1000_SUCCESS at any other case.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
	e_dbg("e1000_set_d3_lplu_state");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
	if (hw->phy_type != e1000_phy_igp)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
	/* During driver activity LPLU should not be used or it will attain link
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
	 * from the lowest speeds starting from 10Mbps. The capability is used for
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
	 * Dx transitions and states */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
	if (hw->mac_type == e1000_82541_rev_2
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
	    || hw->mac_type == e1000_82547_rev_2) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
		    e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
	if (!active) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
		if (hw->mac_type == e1000_82541_rev_2 ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
		    hw->mac_type == e1000_82547_rev_2) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
			phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
			    e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
						phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
		 * Dx states where the power conservation is most important.  During
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
		 * driver activity we should enable SmartSpeed, so performance is
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
		 * maintained. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
		if (hw->smart_speed == e1000_smart_speed_on) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
					       &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
			phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
						phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
		} else if (hw->smart_speed == e1000_smart_speed_off) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
					       &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
						phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
	} else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
		   || (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
		   || (hw->autoneg_advertised ==
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
		       AUTONEG_ADVERTISE_10_100_ALL)) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
		if (hw->mac_type == e1000_82541_rev_2 ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
		    hw->mac_type == e1000_82547_rev_2) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
			phy_data |= IGP01E1000_GMII_FLEX_SPD;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
			ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
			    e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
						phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
			if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
				return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
		}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
		/* When LPLU is enabled we should disable SmartSpeed */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
		    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
				       &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
		phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
		ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
		    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
					phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
 * e1000_set_vco_speed
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
 * Change VCO speed register to improve Bit Error Rate performance of SERDES.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
static s32 e1000_set_vco_speed(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
	u16 default_page = 0;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
	u16 phy_data;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
	e_dbg("e1000_set_vco_speed");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
	switch (hw->mac_type) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
	case e1000_82545_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
	case e1000_82546_rev_3:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
		break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5635
	default:
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5636
		return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5637
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5638
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5639
	/* Set PHY register 30, page 5, bit 8 to 0 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5640
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5641
	ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5642
	    e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5643
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5644
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5645
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5646
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5647
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5648
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5649
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5650
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5651
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5652
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5653
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5654
	phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5655
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5656
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5657
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5658
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5659
	/* Set PHY register 30, page 4, bit 11 to 1 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5660
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5661
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5662
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5663
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5664
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5665
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5666
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5667
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5668
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5669
	phy_data |= M88E1000_PHY_VCO_REG_BIT11;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5670
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5671
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5672
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5673
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5674
	ret_val =
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5675
	    e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5676
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5677
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5678
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5679
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5680
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5681
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5682
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5683
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5684
 * e1000_enable_mng_pass_thru - check for bmc pass through
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5685
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5686
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5687
 * Verifies the hardware needs to allow ARPs to be processed by the host
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5688
 * returns: - true/false
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5689
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5690
u32 e1000_enable_mng_pass_thru(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5691
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5692
	u32 manc;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5693
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5694
	if (hw->asf_firmware_present) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5695
		manc = er32(MANC);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5696
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5697
		if (!(manc & E1000_MANC_RCV_TCO_EN) ||
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5698
		    !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5699
			return false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5700
		if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5701
			return true;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5702
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5703
	return false;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5704
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5705
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5706
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5707
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5708
	s32 ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5709
	u16 mii_status_reg;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5710
	u16 i;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5711
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5712
	/* Polarity reversal workaround for forced 10F/10H links. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5713
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5714
	/* Disable the transmitter on the PHY */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5715
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5716
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5717
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5718
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5719
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5720
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5721
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5722
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5723
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5724
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5725
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5726
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5727
	/* This loop will early-out if the NO link condition has been met. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5728
	for (i = PHY_FORCE_TIME; i > 0; i--) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5729
		/* Read the MII Status Register and wait for Link Status bit
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5730
		 * to be clear.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5731
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5732
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5733
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5734
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5735
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5736
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5737
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5738
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5739
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5740
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5741
		if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5742
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5743
		msleep(100);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5744
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5745
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5746
	/* Recommended delay time after link has been lost */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5747
	msleep(1000);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5748
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5749
	/* Now we will re-enable th transmitter on the PHY */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5750
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5751
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5752
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5753
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5754
	msleep(50);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5755
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5756
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5757
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5758
	msleep(50);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5759
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5760
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5761
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5762
	msleep(50);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5763
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5764
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5765
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5766
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5767
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5768
	if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5769
		return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5770
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5771
	/* This loop will early-out if the link condition has been met. */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5772
	for (i = PHY_FORCE_TIME; i > 0; i--) {
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5773
		/* Read the MII Status Register and wait for Link Status bit
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5774
		 * to be set.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5775
		 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5776
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5777
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5778
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5779
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5780
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5781
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5782
		if (ret_val)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5783
			return ret_val;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5784
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5785
		if (mii_status_reg & MII_SR_LINK_STATUS)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5786
			break;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5787
		msleep(100);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5788
	}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5789
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5790
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5791
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5792
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5793
 * e1000_get_auto_rd_done
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5794
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5795
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5796
 * Check for EEPROM Auto Read bit done.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5797
 * returns: - E1000_ERR_RESET if fail to reset MAC
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5798
 *            E1000_SUCCESS at any other case.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5799
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5800
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5801
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5802
	e_dbg("e1000_get_auto_rd_done");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5803
	msleep(5);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5804
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5805
}
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5806
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5807
/**
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5808
 * e1000_get_phy_cfg_done
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5809
 * @hw: Struct containing variables accessed by shared code
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5810
 *
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5811
 * Checks if the PHY configuration is done
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5812
 * returns: - E1000_ERR_RESET if fail to reset MAC
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5813
 *            E1000_SUCCESS at any other case.
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5814
 */
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5815
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5816
{
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5817
	e_dbg("e1000_get_phy_cfg_done");
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5818
	msleep(10);
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5819
	return E1000_SUCCESS;
d1bd39013a32 Added e1000 driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5820
}