devices/e1000/e1000_hw-3.16-orig.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2588 792892ab4806
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.
2588
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
/* e1000_hw.c
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
 * Shared functions for accessing and configuring the MAC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include "e1000.h"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
static s32 e1000_check_downshift(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static s32 e1000_check_polarity(struct e1000_hw *hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
				e1000_rev_polarity *polarity);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
static void e1000_clear_vfta(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
					      bool link_up);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
static s32 e1000_detect_gig_phy(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
				  u16 *max_length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
static s32 e1000_id_led_init(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
static void e1000_init_rx_addrs(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
				  struct e1000_phy_info *phy_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
				  struct e1000_phy_info *phy_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
static s32 e1000_wait_autoneg(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
static s32 e1000_set_phy_type(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
static void e1000_phy_init_script(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
static s32 e1000_setup_copper_link(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
792892ab4806 Added all drivers for kernel 3.16.
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);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
				  u16 words, u16 *data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
					u16 words, u16 *data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd);
792892ab4806 Added all drivers for kernel 3.16.
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);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
				  u16 phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
				 u16 *phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
static s32 e1000_acquire_eeprom(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
static void e1000_release_eeprom(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
static void e1000_standby_eeprom(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
static s32 e1000_set_vco_speed(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
static s32 e1000_set_phy_mode(struct e1000_hw *hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
				u16 *data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
				 u16 *data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
/* IGP cable length table */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
static const
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
u16 e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = {
792892ab4806 Added all drivers for kernel 3.16.
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,
792892ab4806 Added all drivers for kernel 3.16.
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,
792892ab4806 Added all drivers for kernel 3.16.
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,
792892ab4806 Added all drivers for kernel 3.16.
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,
792892ab4806 Added all drivers for kernel 3.16.
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,
792892ab4806 Added all drivers for kernel 3.16.
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,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	    100,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	    110, 110,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	    120, 120
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static DEFINE_SPINLOCK(e1000_eeprom_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
static DEFINE_SPINLOCK(e1000_phy_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
 * e1000_set_phy_type - Set the phy type member in the hw struct.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static s32 e1000_set_phy_type(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	if (hw->mac_type == e1000_undefined)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
		return -E1000_ERR_PHY_TYPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
	switch (hw->phy_id) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	case M88E1000_E_PHY_ID:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	case M88E1000_I_PHY_ID:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	case M88E1011_I_PHY_ID:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	case M88E1111_I_PHY_ID:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	case M88E1118_E_PHY_ID:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
		hw->phy_type = e1000_phy_m88;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	case IGP01E1000_I_PHY_ID:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
		if (hw->mac_type == e1000_82541 ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
		    hw->mac_type == e1000_82541_rev_2 ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
		    hw->mac_type == e1000_82547 ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
		    hw->mac_type == e1000_82547_rev_2)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
			hw->phy_type = e1000_phy_igp;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
	case RTL8211B_PHY_ID:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
		hw->phy_type = e1000_phy_8211;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
	case RTL8201N_PHY_ID:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
		hw->phy_type = e1000_phy_8201;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
		/* Should never have loaded on this device */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
		hw->phy_type = e1000_phy_undefined;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
		return -E1000_ERR_PHY_TYPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
 * e1000_phy_init_script - IGP phy init script - initializes the GbE PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
static void e1000_phy_init_script(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	u32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
	u16 phy_saved_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
	if (hw->phy_init_script) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
		msleep(20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
		/* Save off the current value of register 0x2F5B to be restored
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
		 * at the end of this routine.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
		ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
		/* Disabled the PHY transmitter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
		e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
		msleep(20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
		e1000_write_phy_reg(hw, 0x0000, 0x0140);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
		msleep(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
		switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
		case e1000_82541:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
		case e1000_82547:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
			e1000_write_phy_reg(hw, 0x1F95, 0x0001);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
			e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
			e1000_write_phy_reg(hw, 0x1F79, 0x0018);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
			e1000_write_phy_reg(hw, 0x1F30, 0x1600);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
			e1000_write_phy_reg(hw, 0x1F31, 0x0014);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
			e1000_write_phy_reg(hw, 0x1F32, 0x161C);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
			e1000_write_phy_reg(hw, 0x1F94, 0x0003);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
			e1000_write_phy_reg(hw, 0x1F96, 0x003F);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
			e1000_write_phy_reg(hw, 0x2010, 0x0008);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
		case e1000_82541_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
		case e1000_82547_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
			e1000_write_phy_reg(hw, 0x1F73, 0x0099);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
		e1000_write_phy_reg(hw, 0x0000, 0x3300);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
		msleep(20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
		/* Now enable the transmitter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
		e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
		if (hw->mac_type == e1000_82547) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
			u16 fused, fine, coarse;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
			/* Move to analog registers page */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
			e1000_read_phy_reg(hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
					   IGP01E1000_ANALOG_SPARE_FUSE_STATUS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
					   &fused);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
			if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
				e1000_read_phy_reg(hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
						   IGP01E1000_ANALOG_FUSE_STATUS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
						   &fused);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
				fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
				coarse =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
				    fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
				if (coarse >
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
				    IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
					coarse -=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
					    IGP01E1000_ANALOG_FUSE_COARSE_10;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
					fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
				} else if (coarse ==
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
					   IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
					fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
				fused =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
				    (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
				    (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
				    (coarse &
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
				     IGP01E1000_ANALOG_FUSE_COARSE_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
				e1000_write_phy_reg(hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
						    IGP01E1000_ANALOG_FUSE_CONTROL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
						    fused);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
				e1000_write_phy_reg(hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
						    IGP01E1000_ANALOG_FUSE_BYPASS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
						    IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
 * e1000_set_mac_type - Set the mac type member in the hw struct.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
s32 e1000_set_mac_type(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	switch (hw->device_id) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	case E1000_DEV_ID_82542:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
		switch (hw->revision_id) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
		case E1000_82542_2_0_REV_ID:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
			hw->mac_type = e1000_82542_rev2_0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
		case E1000_82542_2_1_REV_ID:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
			hw->mac_type = e1000_82542_rev2_1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
			/* Invalid 82542 revision ID */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
			return -E1000_ERR_MAC_TYPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	case E1000_DEV_ID_82543GC_FIBER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	case E1000_DEV_ID_82543GC_COPPER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
		hw->mac_type = e1000_82543;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	case E1000_DEV_ID_82544EI_COPPER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	case E1000_DEV_ID_82544EI_FIBER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	case E1000_DEV_ID_82544GC_COPPER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	case E1000_DEV_ID_82544GC_LOM:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
		hw->mac_type = e1000_82544;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	case E1000_DEV_ID_82540EM:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	case E1000_DEV_ID_82540EM_LOM:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	case E1000_DEV_ID_82540EP:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	case E1000_DEV_ID_82540EP_LOM:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	case E1000_DEV_ID_82540EP_LP:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
		hw->mac_type = e1000_82540;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	case E1000_DEV_ID_82545EM_COPPER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	case E1000_DEV_ID_82545EM_FIBER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
		hw->mac_type = e1000_82545;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	case E1000_DEV_ID_82545GM_COPPER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	case E1000_DEV_ID_82545GM_FIBER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	case E1000_DEV_ID_82545GM_SERDES:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
		hw->mac_type = e1000_82545_rev_3;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	case E1000_DEV_ID_82546EB_COPPER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	case E1000_DEV_ID_82546EB_FIBER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		hw->mac_type = e1000_82546;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	case E1000_DEV_ID_82546GB_COPPER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	case E1000_DEV_ID_82546GB_FIBER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	case E1000_DEV_ID_82546GB_SERDES:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	case E1000_DEV_ID_82546GB_PCIE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	case E1000_DEV_ID_82546GB_QUAD_COPPER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
		hw->mac_type = e1000_82546_rev_3;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	case E1000_DEV_ID_82541EI:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	case E1000_DEV_ID_82541EI_MOBILE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	case E1000_DEV_ID_82541ER_LOM:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
		hw->mac_type = e1000_82541;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	case E1000_DEV_ID_82541ER:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	case E1000_DEV_ID_82541GI:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	case E1000_DEV_ID_82541GI_LF:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	case E1000_DEV_ID_82541GI_MOBILE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
		hw->mac_type = e1000_82541_rev_2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	case E1000_DEV_ID_82547EI:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	case E1000_DEV_ID_82547EI_MOBILE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
		hw->mac_type = e1000_82547;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	case E1000_DEV_ID_82547GI:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
		hw->mac_type = e1000_82547_rev_2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	case E1000_DEV_ID_INTEL_CE4100_GBE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
		hw->mac_type = e1000_ce4100;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
		/* Should never have loaded on this device */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
		return -E1000_ERR_MAC_TYPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	case e1000_82541:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	case e1000_82547:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
	case e1000_82541_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	case e1000_82547_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
		hw->asf_firmware_present = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	/* The 82543 chip does not count tx_carrier_errors properly in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	 * FD mode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
	if (hw->mac_type == e1000_82543)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		hw->bad_tx_carr_stats_fd = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
	if (hw->mac_type > e1000_82544)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		hw->has_smbus = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
 * e1000_set_media_type - Set media type and TBI compatibility.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
void e1000_set_media_type(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	u32 status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
	if (hw->mac_type != e1000_82543) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
		/* tbi_compatibility is only valid on 82543 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
		hw->tbi_compatibility_en = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	switch (hw->device_id) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	case E1000_DEV_ID_82545GM_SERDES:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	case E1000_DEV_ID_82546GB_SERDES:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		hw->media_type = e1000_media_type_internal_serdes;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
		switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
		case e1000_82542_rev2_0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
		case e1000_82542_rev2_1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
			hw->media_type = e1000_media_type_fiber;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
		case e1000_ce4100:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
			hw->media_type = e1000_media_type_copper;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
			status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
			if (status & E1000_STATUS_TBIMODE) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
				hw->media_type = e1000_media_type_fiber;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
				/* tbi_compatibility not valid on fiber */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
				hw->tbi_compatibility_en = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
				hw->media_type = e1000_media_type_copper;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
 * e1000_reset_hw - reset the hardware completely
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
 * Reset the transmit and receive units; mask and clear all interrupts.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
s32 e1000_reset_hw(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
	u32 ctrl_ext;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
	u32 icr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	u32 manc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	u32 led_ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	/* For 82542 (rev 2.0), disable MWI before issuing a device reset */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	if (hw->mac_type == e1000_82542_rev2_0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
		e_dbg("Disabling MWI on 82542 rev 2.0\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
		e1000_pci_clear_mwi(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	/* Clear interrupt mask to stop board from generating interrupts */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	e_dbg("Masking off all interrupts\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	ew32(IMC, 0xffffffff);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	/* Disable the Transmit and Receive units.  Then delay to allow
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	 * any pending transactions to complete before we hit the MAC with
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	 * the global reset.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	ew32(RCTL, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	ew32(TCTL, E1000_TCTL_PSP);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	/* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	hw->tbi_compatibility_on = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	/* Delay to allow any outstanding PCI transactions to complete before
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	 * resetting the device
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	msleep(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
	/* Must reset the PHY before resetting the MAC */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
		ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
		msleep(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	/* Issue a global reset to the MAC.  This will reset the chip's
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	 * transmit, receive, DMA, and link units.  It will not effect
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	 * the current PCI configuration.  The global reset bit is self-
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	 * clearing, and should clear within a microsecond.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	e_dbg("Issuing a global reset to MAC\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	case e1000_82544:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	case e1000_82540:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
	case e1000_82545:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	case e1000_82546:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
	case e1000_82541:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	case e1000_82541_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
		/* These controllers can't ack the 64-bit write when issuing the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		 * reset, so use IO-mapping as a workaround to issue the reset
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
		E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	case e1000_82545_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
	case e1000_82546_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
		/* Reset is performed on a shadow of the control register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
		ew32(CTRL_DUP, (ctrl | E1000_CTRL_RST));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	case e1000_ce4100:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
		ew32(CTRL, (ctrl | E1000_CTRL_RST));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	/* After MAC reset, force reload of EEPROM to restore power-on settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	 * to device.  Later controllers reload the EEPROM automatically, so
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	 * just wait for reload to complete.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
	case e1000_82542_rev2_0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	case e1000_82542_rev2_1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	case e1000_82543:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	case e1000_82544:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
		/* Wait for reset to complete */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
		udelay(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
		ctrl_ext = er32(CTRL_EXT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
		ctrl_ext |= E1000_CTRL_EXT_EE_RST;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
		ew32(CTRL_EXT, ctrl_ext);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
		/* Wait for EEPROM reload */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		msleep(2);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	case e1000_82541:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	case e1000_82541_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	case e1000_82547:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	case e1000_82547_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
		/* Wait for EEPROM reload */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		msleep(20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
		/* Auto read done will delay 5ms or poll based on mac type */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
		ret_val = e1000_get_auto_rd_done(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	/* Disable HW ARPs on ASF enabled adapters */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	if (hw->mac_type >= e1000_82540) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
		manc = er32(MANC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		manc &= ~(E1000_MANC_ARP_EN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		ew32(MANC, manc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
		e1000_phy_init_script(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
		/* Configure activity LED after PHY reset */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
		led_ctrl = er32(LEDCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
		ew32(LEDCTL, led_ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	/* Clear interrupt mask to stop board from generating interrupts */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	e_dbg("Masking off all interrupts\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	ew32(IMC, 0xffffffff);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	/* Clear any pending interrupt events. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	icr = er32(ICR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	/* If MWI was previously enabled, reenable it. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	if (hw->mac_type == e1000_82542_rev2_0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
		if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
			e1000_pci_set_mwi(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
 * e1000_init_hw - Performs basic configuration of the adapter.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
 * Assumes that the controller has previously been reset and is in a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
 * post-reset uninitialized state. Initializes the receive address registers,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
 * multicast table, and VLAN filter table. Calls routines to setup link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
 * configuration and flow control settings. Clears all on-chip counters. Leaves
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
 * the transmit and receive units disabled and uninitialized.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
s32 e1000_init_hw(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	u32 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	u32 mta_size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	u32 ctrl_ext;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	/* Initialize Identification LED */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	ret_val = e1000_id_led_init(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
		e_dbg("Error Initializing Identification LED\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	/* Set the media type and TBI compatibility */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	e1000_set_media_type(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	/* Disabling VLAN filtering. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	e_dbg("Initializing the IEEE VLAN\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
	if (hw->mac_type < e1000_82545_rev_3)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
		ew32(VET, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	e1000_clear_vfta(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	if (hw->mac_type == e1000_82542_rev2_0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		e_dbg("Disabling MWI on 82542 rev 2.0\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
		e1000_pci_clear_mwi(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
		ew32(RCTL, E1000_RCTL_RST);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
		msleep(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	/* Setup the receive address. This involves initializing all of the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	 * Receive Address Registers (RARs 0 - 15).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	e1000_init_rx_addrs(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	if (hw->mac_type == e1000_82542_rev2_0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
		ew32(RCTL, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
		msleep(1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
			e1000_pci_set_mwi(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	/* Zero out the Multicast HASH table */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	e_dbg("Zeroing the MTA\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	mta_size = E1000_MC_TBL_SIZE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	for (i = 0; i < mta_size; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
		/* use write flush to prevent Memory Write Block (MWB) from
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		 * occurring when accessing our register space
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	/* Set the PCI priority bit correctly in the CTRL register.  This
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	 * determines if the adapter gives priority to receives, or if it
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	 * gives equal priority to transmits and receives.  Valid only on
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	 * 82542 and 82543 silicon.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
		ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
		ew32(CTRL, ctrl | E1000_CTRL_PRIOR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	case e1000_82545_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	case e1000_82546_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
		/* Workaround for PCI-X problem when BIOS sets MMRBC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
		 * incorrectly.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		if (hw->bus_type == e1000_bus_type_pcix
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		    && e1000_pcix_get_mmrbc(hw) > 2048)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
			e1000_pcix_set_mmrbc(hw, 2048);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	/* Call a subroutine to configure the link and setup flow control. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
	ret_val = e1000_setup_link(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	/* Set the transmit descriptor write-back policy */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	if (hw->mac_type > e1000_82544) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
		ctrl = er32(TXDCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
		ctrl =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		    (ctrl & ~E1000_TXDCTL_WTHRESH) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
		    E1000_TXDCTL_FULL_TX_DESC_WB;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
		ew32(TXDCTL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	/* Clear all of the statistics registers (clear on read).  It is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	 * important that we do this after we have tried to establish link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
	 * because the symbol error count will increment wildly if there
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	 * is no link.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	e1000_clear_hw_cntrs(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	    hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
		ctrl_ext = er32(CTRL_EXT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
		/* Relaxed ordering must be disabled to avoid a parity
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
		 * error crash in a PCI slot.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
		ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
		ew32(CTRL_EXT, ctrl_ext);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
 * e1000_adjust_serdes_amplitude - Adjust SERDES output amplitude based on EEPROM setting.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
 * @hw: Struct containing variables accessed by shared code.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
	u16 eeprom_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	if (hw->media_type != e1000_media_type_internal_serdes)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	case e1000_82545_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	case e1000_82546_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
	                            &eeprom_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	if (eeprom_data != EEPROM_RESERVED_WORD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
		/* Adjust SERDES output amplitude only. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
		eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
		    e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
 * e1000_setup_link - Configures flow control and link settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
 * Determines which flow control settings to use. Calls the appropriate media-
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
 * specific link configuration function. Configures the flow control settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
 * Assuming the adapter has a valid link partner, a valid link should be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
 * established. Assumes the hardware has previously been reset and the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
 * transmitter and receiver are not enabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
s32 e1000_setup_link(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	u32 ctrl_ext;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	u16 eeprom_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	/* Read and store word 0x0F of the EEPROM. This word contains bits
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	 * that determine the hardware's default PAUSE (flow control) mode,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	 * a bit that determines whether the HW defaults to enabling or
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	 * disabling auto-negotiation, and the direction of the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	 * SW defined pins. If there is no SW over-ride of the flow
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	 * control setting, then the variable hw->fc will
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	 * be initialized based on a value in the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	if (hw->fc == E1000_FC_DEFAULT) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
		ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
					    1, &eeprom_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
			e_dbg("EEPROM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
			return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
			hw->fc = E1000_FC_NONE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
		else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
			 EEPROM_WORD0F_ASM_DIR)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
			hw->fc = E1000_FC_TX_PAUSE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
			hw->fc = E1000_FC_FULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	/* We want to save off the original Flow Control configuration just
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	 * in case we get disconnected and then reconnected into a different
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	 * hub or switch with different Flow Control capabilities.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	if (hw->mac_type == e1000_82542_rev2_0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		hw->fc &= (~E1000_FC_TX_PAUSE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
		hw->fc &= (~E1000_FC_RX_PAUSE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	hw->original_fc = hw->fc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	/* Take the 4 bits from EEPROM word 0x0F that determine the initial
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	 * polarity value for the SW controlled pins, and setup the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	 * Extended Device Control reg with that info.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	 * This is needed because one of the SW controlled pins is used for
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	 * signal detection.  So this should be done before e1000_setup_pcs_link()
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	 * or e1000_phy_setup() is called.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	if (hw->mac_type == e1000_82543) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
					    1, &eeprom_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
			e_dbg("EEPROM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
			return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
		ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
			    SWDPIO__EXT_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
		ew32(CTRL_EXT, ctrl_ext);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	/* Call the necessary subroutine to configure the link. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	ret_val = (hw->media_type == e1000_media_type_copper) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	    e1000_setup_copper_link(hw) : e1000_setup_fiber_serdes_link(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	/* Initialize the flow control address, type, and PAUSE timer
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	 * registers to their default values.  This is done even if flow
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	 * control is disabled, because it does not hurt anything to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	 * initialize these registers.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	e_dbg("Initializing the Flow Control address, type and timer regs\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	ew32(FCT, FLOW_CONTROL_TYPE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	ew32(FCTTV, hw->fc_pause_time);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	/* Set the flow control receive threshold registers.  Normally,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	 * these registers will be set to a default threshold that may be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	 * adjusted later by the driver's runtime code.  However, if the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	 * ability to transmit pause frames in not enabled, then these
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	 * registers will be set to 0.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
	if (!(hw->fc & E1000_FC_TX_PAUSE)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
		ew32(FCRTL, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
		ew32(FCRTH, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
		/* We need to set up the Receive Threshold high and low water
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
		 * marks as well as (optionally) enabling the transmission of
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
		 * XON frames.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
		if (hw->fc_send_xon) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
			ew32(FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
			ew32(FCRTH, hw->fc_high_water);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
			ew32(FCRTL, hw->fc_low_water);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
			ew32(FCRTH, hw->fc_high_water);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
 * e1000_setup_fiber_serdes_link - prepare fiber or serdes link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
 * Manipulates Physical Coding Sublayer functions in order to configure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
 * link. Assumes the hardware has been previously reset and the transmitter
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
 * and receiver are not enabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	u32 status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	u32 txcw = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	u32 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	u32 signal = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	/* On adapters with a MAC newer than 82544, SWDP 1 will be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	 * set when the optics detect a signal. On older adapters, it will be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	 * cleared when there is a signal.  This applies to fiber media only.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	 * If we're on serdes media, adjust the output amplitude to value
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	 * set in the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	if (hw->media_type == e1000_media_type_fiber)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
		signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	ret_val = e1000_adjust_serdes_amplitude(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	/* Take the link out of reset */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	ctrl &= ~(E1000_CTRL_LRST);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	/* Adjust VCO speed to improve BER performance */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
	ret_val = e1000_set_vco_speed(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	e1000_config_collision_dist(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	/* Check for a software override of the flow control settings, and setup
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	 * the device accordingly.  If auto-negotiation is enabled, then
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	 * software will have to set the "PAUSE" bits to the correct value in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	 * the Tranmsit Config Word Register (TXCW) and re-start
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	 * auto-negotiation.  However, if auto-negotiation is disabled, then
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	 * software will have to manually configure the two flow control enable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	 * bits in the CTRL register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	 * The possible values of the "fc" parameter are:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	 *  0:  Flow control is completely disabled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	 *  1:  Rx flow control is enabled (we can receive pause frames, but
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	 *      not send pause frames).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	 *  2:  Tx flow control is enabled (we can send pause frames but we do
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	 *      not support receiving pause frames).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	 *  3:  Both Rx and TX flow control (symmetric) are enabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	switch (hw->fc) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	case E1000_FC_NONE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		/* Flow ctrl is completely disabled by a software over-ride */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	case E1000_FC_RX_PAUSE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
		/* Rx Flow control is enabled and Tx Flow control is disabled by
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
		 * a software over-ride. Since there really isn't a way to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
		 * advertise that we are capable of Rx Pause ONLY, we will
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
		 * advertise that we support both symmetric and asymmetric Rx
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		 * PAUSE. Later, we will disable the adapter's ability to send
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		 * PAUSE frames.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	case E1000_FC_TX_PAUSE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
		/* Tx Flow control is enabled, and Rx Flow control is disabled,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
		 * by a software over-ride.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	case E1000_FC_FULL:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
		/* Flow control (both Rx and Tx) is enabled by a software
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		 * over-ride.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		e_dbg("Flow control param set incorrectly\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	/* Since auto-negotiation is enabled, take the link out of reset (the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	 * link will be in reset, because we previously reset the chip). This
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	 * will restart auto-negotiation.  If auto-negotiation is successful
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	 * then the link-up status bit will be set and the flow control enable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	 * bits (RFCE and TFCE) will be set according to their negotiated value.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	e_dbg("Auto-negotiation enabled\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	ew32(TXCW, txcw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	hw->txcw = txcw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	msleep(1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	/* If we have a signal (the cable is plugged in) then poll for a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	 * "Link-Up" indication in the Device Status Register.  Time-out if a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	 * link isn't seen in 500 milliseconds seconds (Auto-negotiation should
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	 * complete in less than 500 milliseconds even if the other end is doing
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	 * it in SW). For internal serdes, we just assume a signal is present,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	 * then poll.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	if (hw->media_type == e1000_media_type_internal_serdes ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	    (er32(CTRL) & E1000_CTRL_SWDPIN1) == signal) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
		e_dbg("Looking for Link\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
		for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
			msleep(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
			status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
			if (status & E1000_STATUS_LU)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		if (i == (LINK_UP_TIMEOUT / 10)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
			e_dbg("Never got a valid link from auto-neg!!!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
			hw->autoneg_failed = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
			/* AutoNeg failed to achieve a link, so we'll call
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
			 * e1000_check_for_link. This routine will force the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
			 * link up if we detect a signal. This will allow us to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
			 * communicate with non-autonegotiating link partners.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
			ret_val = e1000_check_for_link(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
			if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
				e_dbg("Error while checking for link\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
			hw->autoneg_failed = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
			hw->autoneg_failed = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
			e_dbg("Valid Link Found\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
		e_dbg("No Signal Detected\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
 * e1000_copper_link_rtl_setup - Copper link setup for e1000_phy_rtl series.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
 * Commits changes to PHY configuration by calling e1000_phy_reset().
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
static s32 e1000_copper_link_rtl_setup(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	/* SW reset the PHY so all changes take effect */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	ret_val = e1000_phy_reset(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		e_dbg("Error Resetting the PHY\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
static s32 gbe_dhg_phy_setup(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	u32 ctrl_aux;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	switch (hw->phy_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	case e1000_phy_8211:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		ret_val = e1000_copper_link_rtl_setup(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
			e_dbg("e1000_copper_link_rtl_setup failed!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	case e1000_phy_8201:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
		/* Set RMII mode */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		ctrl_aux = er32(CTL_AUX);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		ctrl_aux |= E1000_CTL_AUX_RMII;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
		ew32(CTL_AUX, ctrl_aux);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
		/* Disable the J/K bits required for receive */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
		ctrl_aux = er32(CTL_AUX);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
		ctrl_aux |= 0x4;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		ctrl_aux &= ~0x2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
		ew32(CTL_AUX, ctrl_aux);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
		ret_val = e1000_copper_link_rtl_setup(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
			e_dbg("e1000_copper_link_rtl_setup failed!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		e_dbg("Error Resetting the PHY\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		return E1000_ERR_PHY_TYPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
 * e1000_copper_link_preconfig - early configuration for copper
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
 * Make sure we have a valid PHY and change PHY mode before link setup.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
static s32 e1000_copper_link_preconfig(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	/* With 82543, we need to force speed and duplex on the MAC equal to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	 * what the PHY speed and duplex configuration is. In addition, we need
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	 * to perform a hardware reset on the PHY to take it out of reset.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	if (hw->mac_type > e1000_82543) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
		ctrl |= E1000_CTRL_SLU;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
		ctrl |=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		    (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
		ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		ret_val = e1000_phy_hw_reset(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	/* Make sure we have a valid PHY */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	ret_val = e1000_detect_gig_phy(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		e_dbg("Error, did not detect valid phy.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	e_dbg("Phy ID = %x\n", hw->phy_id);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	/* Set PHY to class A mode (if necessary) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	ret_val = e1000_set_phy_mode(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
	if ((hw->mac_type == e1000_82545_rev_3) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	    (hw->mac_type == e1000_82546_rev_3)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		phy_data |= 0x00000008;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	if (hw->mac_type <= e1000_82543 ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	    hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	    hw->mac_type == e1000_82541_rev_2
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	    || hw->mac_type == e1000_82547_rev_2)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
		hw->phy_reset_disable = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
 * e1000_copper_link_igp_setup - Copper link setup for e1000_phy_igp series.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
static s32 e1000_copper_link_igp_setup(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	u32 led_ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
	if (hw->phy_reset_disable)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	ret_val = e1000_phy_reset(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		e_dbg("Error Resetting the PHY\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	/* Wait 15ms for MAC to configure PHY from eeprom settings */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	msleep(15);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	/* Configure activity LED after PHY reset */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	led_ctrl = er32(LEDCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	led_ctrl &= IGP_ACTIVITY_LED_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
	led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	ew32(LEDCTL, led_ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	/* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	if (hw->phy_type == e1000_phy_igp) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
		/* disable lplu d3 during driver init */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
		ret_val = e1000_set_d3_lplu_state(hw, false);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
			e_dbg("Error Disabling LPLU D3\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	/* Configure mdi-mdix settings */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
		hw->dsp_config_state = e1000_dsp_config_disabled;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		/* Force MDI for earlier revs of the IGP PHY */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		phy_data &=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
		    ~(IGP01E1000_PSCR_AUTO_MDIX |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
		      IGP01E1000_PSCR_FORCE_MDI_MDIX);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		hw->mdix = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		hw->dsp_config_state = e1000_dsp_config_enabled;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		switch (hw->mdix) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		case 1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
			phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		case 2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
			phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		case 0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
			phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	/* set auto-master slave resolution settings */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	if (hw->autoneg) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
		e1000_ms_type phy_ms_setting = hw->master_slave;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		if (hw->ffe_config_state == e1000_ffe_config_active)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
			hw->ffe_config_state = e1000_ffe_config_enabled;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		if (hw->dsp_config_state == e1000_dsp_config_activated)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
			hw->dsp_config_state = e1000_dsp_config_enabled;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		/* when autonegotiation advertisement is only 1000Mbps then we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		 * should disable SmartSpeed and enable Auto MasterSlave
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		 * resolution as hardware default.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
		if (hw->autoneg_advertised == ADVERTISE_1000_FULL) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
			/* Disable SmartSpeed */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
					       &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
						phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
			/* Set auto Master/Slave resolution process */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
			    e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
			phy_data &= ~CR_1000T_MS_ENABLE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
			    e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		/* load defaults for future use */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
		hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		    ((phy_data & CR_1000T_MS_VALUE) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
		     e1000_ms_force_master :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		     e1000_ms_force_slave) : e1000_ms_auto;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
		switch (phy_ms_setting) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		case e1000_ms_force_master:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
			phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		case e1000_ms_force_slave:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
			phy_data |= CR_1000T_MS_ENABLE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
			phy_data &= ~(CR_1000T_MS_VALUE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		case e1000_ms_auto:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
			phy_data &= ~CR_1000T_MS_ENABLE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
 * e1000_copper_link_mgp_setup - Copper link setup for e1000_phy_m88 series.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
static s32 e1000_copper_link_mgp_setup(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	if (hw->phy_reset_disable)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	/* Enable CRS on TX. This must be set for half-duplex operation. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	/* Options:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
	 *   MDI/MDI-X = 0 (default)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
	 *   0 - Auto for all speeds
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	 *   1 - MDI mode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	 *   2 - MDI-X mode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	switch (hw->mdix) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	case 1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	case 2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	case 3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	case 0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
	/* Options:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	 *   disable_polarity_correction = 0 (default)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	 *       Automatic Correction for Reversed Cable Polarity
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	 *   0 - Disabled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	 *   1 - Enabled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	if (hw->disable_polarity_correction == 1)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	if (hw->phy_revision < M88E1011_I_REV_4) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		/* Force TX_CLK in the Extended PHY Specific Control Register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
		 * to 25MHz clock.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
		    e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
				       &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
		if ((hw->phy_revision == E1000_REVISION_2) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
		    (hw->phy_id == M88E1111_I_PHY_ID)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
			/* Vidalia Phy, set the downshift counter to 5x */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
			phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
			ret_val = e1000_write_phy_reg(hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
						      M88E1000_EXT_PHY_SPEC_CTRL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
						      phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
			/* Configure Master and Slave downshift values */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
				      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
			ret_val = e1000_write_phy_reg(hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
						      M88E1000_EXT_PHY_SPEC_CTRL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
						      phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	/* SW Reset the PHY so all changes take effect */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	ret_val = e1000_phy_reset(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
		e_dbg("Error Resetting the PHY\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
 * e1000_copper_link_autoneg - setup auto-neg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
 * Setup auto-negotiation and flow control advertisements,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
 * and then perform auto-negotiation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
	/* Perform some bounds checking on the hw->autoneg_advertised
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	 * parameter.  If this variable is zero, then set it to the default.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	/* If autoneg_advertised is zero, we assume it was not defaulted
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
	 * by the calling code so we set to advertise full capability.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	if (hw->autoneg_advertised == 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
		hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	/* IFE/RTL8201N PHY only supports 10/100 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	if (hw->phy_type == e1000_phy_8201)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
		hw->autoneg_advertised &= AUTONEG_ADVERTISE_10_100_ALL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	e_dbg("Reconfiguring auto-neg advertisement params\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	ret_val = e1000_phy_setup_autoneg(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
		e_dbg("Error Setting up Auto-Negotiation\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	e_dbg("Restarting Auto-Neg\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
	 * the Auto Neg Restart bit in the PHY control register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
	phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	/* Does the user want to wait for Auto-Neg to complete here, or
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	 * check at a later time (for example, callback routine).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	if (hw->wait_autoneg_complete) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
		ret_val = e1000_wait_autoneg(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
			e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
			    ("Error while waiting for autoneg to complete\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	hw->get_link_status = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
 * e1000_copper_link_postconfig - post link setup
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
 * Config the MAC and the PHY after link is up.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
 *   1) Set up the MAC to the current PHY speed/duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
 *      if we are on 82543.  If we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
 *      are on newer silicon, we only need to configure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
 *      collision distance in the Transmit Control Register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
 *   2) Set up flow control on the MAC to that established with
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
 *      the link partner.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
 *   3) Config DSP to improve Gigabit link quality for some PHY revisions.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
static s32 e1000_copper_link_postconfig(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
	if ((hw->mac_type >= e1000_82544) && (hw->mac_type != e1000_ce4100)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		e1000_config_collision_dist(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
		ret_val = e1000_config_mac_to_phy(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
			e_dbg("Error configuring MAC to PHY settings\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	ret_val = e1000_config_fc_after_link_up(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
		e_dbg("Error Configuring Flow Control\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	/* Config DSP to improve Giga link quality */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
	if (hw->phy_type == e1000_phy_igp) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
		ret_val = e1000_config_dsp_after_link_change(hw, true);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
			e_dbg("Error Configuring DSP after link up\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
 * e1000_setup_copper_link - phy/speed/duplex setting
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
 * Detects which PHY is present and sets up the speed and duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
static s32 e1000_setup_copper_link(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	u16 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	/* Check if it is a valid PHY and set PHY mode if necessary. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
	ret_val = e1000_copper_link_preconfig(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	if (hw->phy_type == e1000_phy_igp) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
		ret_val = e1000_copper_link_igp_setup(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	} else if (hw->phy_type == e1000_phy_m88) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
		ret_val = e1000_copper_link_mgp_setup(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
		ret_val = gbe_dhg_phy_setup(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
			e_dbg("gbe_dhg_phy_setup failed!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	if (hw->autoneg) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
		/* Setup autoneg and flow control advertisement
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
		 * and perform autonegotiation
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
		ret_val = e1000_copper_link_autoneg(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
		/* PHY will be set to 10H, 10F, 100H,or 100F
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
		 * depending on value from forced_speed_duplex.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
		e_dbg("Forcing speed and duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
		ret_val = e1000_phy_force_speed_duplex(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
			e_dbg("Error Forcing Speed and Duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	/* Check link status. Wait up to 100 microseconds for link to become
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	 * valid.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	for (i = 0; i < 10; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
		if (phy_data & MII_SR_LINK_STATUS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
			/* Config the MAC and PHY after link is up */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
			ret_val = e1000_copper_link_postconfig(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
			e_dbg("Valid link established!!!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
			return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		udelay(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
	e_dbg("Unable to establish link!!!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
 * e1000_phy_setup_autoneg - phy settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
 * Configures PHY autoneg and flow control advertisement settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	u16 mii_autoneg_adv_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	u16 mii_1000t_ctrl_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	/* Read the MII 1000Base-T Control Register (Address 9). */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	else if (hw->phy_type == e1000_phy_8201)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
		mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	/* Need to parse both autoneg_advertised and fc and set up
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	 * the appropriate PHY registers.  First we will parse for
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	 * autoneg_advertised software override.  Since we can advertise
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
	 * a plethora of combinations, we need to check each bit
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	 * individually.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
	 * the  1000Base-T Control Register (Address 9).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
	mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
	mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
	e_dbg("autoneg_advertised %x\n", hw->autoneg_advertised);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	/* Do we want to advertise 10 Mb Half Duplex? */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
		e_dbg("Advertise 10mb Half duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	/* Do we want to advertise 10 Mb Full Duplex? */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
	if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
		e_dbg("Advertise 10mb Full duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
	/* Do we want to advertise 100 Mb Half Duplex? */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
		e_dbg("Advertise 100mb Half duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	/* Do we want to advertise 100 Mb Full Duplex? */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
		e_dbg("Advertise 100mb Full duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
		e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
		    ("Advertise 1000mb Half duplex requested, request denied!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	/* Do we want to advertise 1000 Mb Full Duplex? */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
	if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
		e_dbg("Advertise 1000mb Full duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	/* Check for a software override of the flow control settings, and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	 * setup the PHY advertisement registers accordingly.  If
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
	 * auto-negotiation is enabled, then software will have to set the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	 * "PAUSE" bits to the correct value in the Auto-Negotiation
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	 * auto-negotiation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	 * The possible values of the "fc" parameter are:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	 *      0:  Flow control is completely disabled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	 *      1:  Rx flow control is enabled (we can receive pause frames
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	 *          but not send pause frames).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	 *      2:  Tx flow control is enabled (we can send pause frames
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	 *          but we do not support receiving pause frames).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	 *  other:  No software override.  The flow control configuration
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	 *          in the EEPROM is used.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	switch (hw->fc) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	case E1000_FC_NONE:	/* 0 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		/* Flow control (RX & TX) is completely disabled by a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		 * software over-ride.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	case E1000_FC_RX_PAUSE:	/* 1 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
		/* RX Flow control is enabled, and TX Flow control is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
		 * disabled, by a software over-ride.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
		/* Since there really isn't a way to advertise that we are
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
		 * capable of RX Pause ONLY, we will advertise that we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		 * support both symmetric and asymmetric RX PAUSE.  Later
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		 * (in e1000_config_fc_after_link_up) we will disable the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		 * hw's ability to send PAUSE frames.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
	case E1000_FC_TX_PAUSE:	/* 2 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
		/* TX Flow control is enabled, and RX Flow control is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
		 * disabled, by a software over-ride.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
	case E1000_FC_FULL:	/* 3 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		/* Flow control (both RX and TX) is enabled by a software
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
		 * over-ride.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		e_dbg("Flow control param set incorrectly\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
	ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
	e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
	if (hw->phy_type == e1000_phy_8201) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		mii_1000t_ctrl_reg = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
		                              mii_1000t_ctrl_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
 * e1000_phy_force_speed_duplex - force link settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
 * Force PHY speed and duplex settings to hw->forced_speed_duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
	u16 mii_ctrl_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
	u16 mii_status_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
	u16 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	/* Turn off Flow control if we are forcing speed and duplex. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	hw->fc = E1000_FC_NONE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	e_dbg("hw->fc = %d\n", hw->fc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	/* Read the Device Control Register. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	/* Set the bits to Force Speed and Duplex in the Device Ctrl Reg. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	ctrl &= ~(DEVICE_SPEED_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
	/* Clear the Auto Speed Detect Enable bit. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	ctrl &= ~E1000_CTRL_ASDE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	/* Read the MII Control Register. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	/* We need to disable autoneg in order to force link and duplex. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	/* Are we forcing Full or Half Duplex? */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	if (hw->forced_speed_duplex == e1000_100_full ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	    hw->forced_speed_duplex == e1000_10_full) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
		/* We want to force full duplex so we SET the full duplex bits
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
		 * in the Device and MII Control Registers.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		ctrl |= E1000_CTRL_FD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
		mii_ctrl_reg |= MII_CR_FULL_DUPLEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
		e_dbg("Full Duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
		/* We want to force half duplex so we CLEAR the full duplex bits
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
		 * in the Device and MII Control Registers.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
		ctrl &= ~E1000_CTRL_FD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
		mii_ctrl_reg &= ~MII_CR_FULL_DUPLEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
		e_dbg("Half Duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	/* Are we forcing 100Mbps??? */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	if (hw->forced_speed_duplex == e1000_100_full ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	    hw->forced_speed_duplex == e1000_100_half) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		/* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		ctrl |= E1000_CTRL_SPD_100;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		mii_ctrl_reg |= MII_CR_SPEED_100;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
		mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		e_dbg("Forcing 100mb ");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
		/* Set the 10Mb bit and turn off the 1000Mb and 100Mb bits. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		mii_ctrl_reg |= MII_CR_SPEED_10;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
		mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		e_dbg("Forcing 10mb ");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	e1000_config_collision_dist(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	/* Write the configured values back to the Device Control Reg. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
	if (hw->phy_type == e1000_phy_m88) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
		/* Clear Auto-Crossover to force MDI manually. M88E1000 requires
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
		 * MDI forced whenever speed are duplex are forced.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
		phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		e_dbg("M88E1000 PSCR: %x\n", phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		/* Need to reset the PHY or these changes will be ignored */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
		mii_ctrl_reg |= MII_CR_RESET;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
		/* Disable MDI-X support for 10/100 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		/* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
		 * forced whenever speed or duplex are forced.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
	/* Write back the modified PHY MII control register. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	udelay(1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	/* The wait_autoneg_complete flag may be a little misleading here.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
	 * Since we are forcing speed and duplex, Auto-Neg is not enabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
	 * But we do want to delay for a period while forcing only so we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
	 * don't generate false No Link messages.  So we will wait here
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
	 * only if the user has set wait_autoneg_complete to 1, which is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	 * the default.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
	if (hw->wait_autoneg_complete) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
		/* We will wait for autoneg to complete. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
		e_dbg("Waiting for forced speed/duplex link.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
		mii_status_reg = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
		/* Wait for autoneg to complete or 4.5 seconds to expire */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
		for (i = PHY_FORCE_TIME; i > 0; i--) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
			/* Read the MII Status Register and wait for Auto-Neg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
			 * Complete bit to be set.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
			if (mii_status_reg & MII_SR_LINK_STATUS)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
			msleep(100);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		if ((i == 0) && (hw->phy_type == e1000_phy_m88)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
			/* We didn't get link.  Reset the DSP and wait again
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
			 * for link.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
			ret_val = e1000_phy_reset_dsp(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
			if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
				e_dbg("Error Resetting PHY DSP\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
		/* This loop will early-out if the link condition has been
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
		 * met
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
		for (i = PHY_FORCE_TIME; i > 0; i--) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
			if (mii_status_reg & MII_SR_LINK_STATUS)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
			msleep(100);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
			/* Read the MII Status Register and wait for Auto-Neg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
			 * Complete bit to be set.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
			    e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
	if (hw->phy_type == e1000_phy_m88) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
		/* Because we reset the PHY above, we need to re-force TX_CLK in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
		 * the Extended PHY Specific Control Register to 25MHz clock.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
		 * This value defaults back to a 2.5MHz clock when the PHY is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
		 * reset.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
		    e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
				       &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		    e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
					phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		/* In addition, because of the s/w reset above, we need to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
		 * enable CRS on Tx.  This must be set for both full and half
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
		 * duplex operation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
		    e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
		phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
		    e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
		    && (!hw->autoneg)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
		    && (hw->forced_speed_duplex == e1000_10_full
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
			|| hw->forced_speed_duplex == e1000_10_half)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
			ret_val = e1000_polarity_reversal_workaround(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
 * e1000_config_collision_dist - set collision distance register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
 * Sets the collision distance in the Transmit Control register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
 * Link should have been established previously. Reads the speed and duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
 * information from the Device Status register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
void e1000_config_collision_dist(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
	u32 tctl, coll_dist;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
	if (hw->mac_type < e1000_82543)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
		coll_dist = E1000_COLLISION_DISTANCE_82542;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
		coll_dist = E1000_COLLISION_DISTANCE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	tctl = er32(TCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	tctl &= ~E1000_TCTL_COLD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
	tctl |= coll_dist << E1000_COLD_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	ew32(TCTL, tctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
	E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
 * e1000_config_mac_to_phy - sync phy and mac settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
 * @mii_reg: data to write to the MII control register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
 * Sets MAC speed and duplex settings to reflect the those in the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
 * The contents of the PHY register containing the needed information need to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
 * be passed in.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
static s32 e1000_config_mac_to_phy(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
	/* 82544 or newer MAC, Auto Speed Detection takes care of
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	 * MAC speed/duplex configuration.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
	if ((hw->mac_type >= e1000_82544) && (hw->mac_type != e1000_ce4100))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
	/* Read the Device Control Register and set the bits to Force Speed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
	 * and Duplex.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	switch (hw->phy_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	case e1000_phy_8201:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
		ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
		if (phy_data & RTL_PHY_CTRL_FD)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
			ctrl |= E1000_CTRL_FD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
			ctrl &= ~E1000_CTRL_FD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
		if (phy_data & RTL_PHY_CTRL_SPD_100)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
			ctrl |= E1000_CTRL_SPD_100;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
			ctrl |= E1000_CTRL_SPD_10;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
		e1000_config_collision_dist(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
		/* Set up duplex in the Device Control and Transmit Control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		 * registers depending on negotiated values.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
					     &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		if (phy_data & M88E1000_PSSR_DPLX)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
			ctrl |= E1000_CTRL_FD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
			ctrl &= ~E1000_CTRL_FD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
		e1000_config_collision_dist(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
		/* Set up speed in the Device Control register depending on
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
		 * negotiated values.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
		if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
			ctrl |= E1000_CTRL_SPD_1000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
		else if ((phy_data & M88E1000_PSSR_SPEED) ==
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
			 M88E1000_PSSR_100MBS)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
			ctrl |= E1000_CTRL_SPD_100;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	/* Write the configured values back to the Device Control Reg. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
 * e1000_force_mac_fc - force flow control settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
 * Forces the MAC's flow control settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
 * Sets the TFCE and RFCE bits in the device control register to reflect
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
 * the adapter settings. TFCE and RFCE need to be explicitly set by
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
 * software when a Copper PHY is used because autonegotiation is managed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
 * by the PHY rather than the MAC. Software must also configure these
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
 * bits when link is forced on a fiber connection.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
s32 e1000_force_mac_fc(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	/* Get the current configuration of the Device Control Register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	/* Because we didn't get link via the internal auto-negotiation
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	 * mechanism (we either forced link or we got link via PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	 * auto-neg), we have to manually enable/disable transmit an
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
	 * receive flow control.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
	 * The "Case" statement below enables/disable flow control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	 * according to the "hw->fc" parameter.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	 * The possible values of the "fc" parameter are:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
	 *      0:  Flow control is completely disabled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	 *      1:  Rx flow control is enabled (we can receive pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	 *          frames but not send pause frames).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	 *      2:  Tx flow control is enabled (we can send pause frames
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
	 *          frames but we do not receive pause frames).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	 *      3:  Both Rx and TX flow control (symmetric) is enabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	 *  other:  No other values should be possible at this point.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	switch (hw->fc) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	case E1000_FC_NONE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
	case E1000_FC_RX_PAUSE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		ctrl &= (~E1000_CTRL_TFCE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
		ctrl |= E1000_CTRL_RFCE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
	case E1000_FC_TX_PAUSE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
		ctrl &= (~E1000_CTRL_RFCE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
		ctrl |= E1000_CTRL_TFCE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	case E1000_FC_FULL:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
		e_dbg("Flow control param set incorrectly\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
	/* Disable TX Flow Control for 82542 (rev 2.0) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
	if (hw->mac_type == e1000_82542_rev2_0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
		ctrl &= (~E1000_CTRL_TFCE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
 * e1000_config_fc_after_link_up - configure flow control after autoneg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
 * Configures flow control settings after link is established
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
 * Should be called immediately after a valid link has been established.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
 * Forces MAC flow control settings if link was forced. When in MII/GMII mode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
 * and autonegotiation is enabled, the MAC flow control settings will be set
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
 * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
 * and RFCE bits will be automatically set to the negotiated flow control mode.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	u16 mii_status_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	u16 mii_nway_adv_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	u16 mii_nway_lp_ability_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	u16 speed;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	u16 duplex;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	/* Check for the case where we have fiber media and auto-neg failed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
	 * so we had to force link.  In this case, we need to force the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
	 * configuration of the MAC to match the "fc" parameter.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
	if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
	    || ((hw->media_type == e1000_media_type_internal_serdes)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
		&& (hw->autoneg_failed))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
	    || ((hw->media_type == e1000_media_type_copper)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
		&& (!hw->autoneg))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
		ret_val = e1000_force_mac_fc(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
			e_dbg("Error forcing flow control settings\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
	/* Check for the case where we have copper media and auto-neg is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	 * enabled.  In this case, we need to check and see if Auto-Neg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	 * has completed, and if so, how the PHY and link partner has
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
	 * flow control configured.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	if ((hw->media_type == e1000_media_type_copper) && hw->autoneg) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
		/* Read the MII Status Register and check to see if AutoNeg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
		 * has completed.  We read this twice because this reg has
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
		 * some "sticky" (latched) bits.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
		if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
			/* The AutoNeg process has completed, so we now need to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
			 * read both the Auto Negotiation Advertisement Register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
			 * (Address 4) and the Auto_Negotiation Base Page
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
			 * Ability Register (Address 5) to determine how flow
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
			 * control was negotiated.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
			ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
						     &mii_nway_adv_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
			ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
						     &mii_nway_lp_ability_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
			/* Two bits in the Auto Negotiation Advertisement
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
			 * Register (Address 4) and two bits in the Auto
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
			 * Negotiation Base Page Ability Register (Address 5)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
			 * determine flow control for both the PHY and the link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
			 * partner.  The following table, taken out of the IEEE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
			 * 802.3ab/D6.0 dated March 25, 1999, describes these
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
			 * PAUSE resolution bits and how flow control is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
			 * determined based upon these settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
			 * NOTE:  DC = Don't Care
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
			 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
			 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
			 *-------|---------|-------|---------|------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
			 *   0   |    0    |  DC   |   DC    | E1000_FC_NONE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
			 *   0   |    1    |   0   |   DC    | E1000_FC_NONE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
			 *   0   |    1    |   1   |    0    | E1000_FC_NONE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
			 *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
			 *   1   |    0    |   0   |   DC    | E1000_FC_NONE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
			 *   1   |    1    |   0   |    0    | E1000_FC_NONE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
			 *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
			 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
			/* Are both PAUSE bits set to 1?  If so, this implies
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
			 * Symmetric Flow Control is enabled at both ends.  The
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
			 * ASM_DIR bits are irrelevant per the spec.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
			 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			 * For Symmetric Flow Control:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
			 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
			 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
			 *-------|---------|-------|---------|------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
			 *   1   |   DC    |   1   |   DC    | E1000_FC_FULL
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
			 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
			if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
			    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
				/* Now we need to check if the user selected Rx
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
				 * ONLY of pause frames.  In this case, we had
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
				 * to advertise FULL flow control because we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
				 * could not advertise Rx ONLY. Hence, we must
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
				 * now check to see if we need to turn OFF the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
				 * TRANSMISSION of PAUSE frames.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
				 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
				if (hw->original_fc == E1000_FC_FULL) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
					hw->fc = E1000_FC_FULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
					e_dbg("Flow Control = FULL.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
				} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
					hw->fc = E1000_FC_RX_PAUSE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
					e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
					    ("Flow Control = RX PAUSE frames only.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
			/* For receiving PAUSE frames ONLY.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
			 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
			 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
			 *-------|---------|-------|---------|------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
			 *   0   |    1    |   1   |    1    | E1000_FC_TX_PAUSE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
			 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
			else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
				 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
			{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
				hw->fc = E1000_FC_TX_PAUSE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
				e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
				    ("Flow Control = TX PAUSE frames only.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
			/* For transmitting PAUSE frames ONLY.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
			 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
			 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
			 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
			 *-------|---------|-------|---------|------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
			 *   1   |    1    |   0   |    1    | E1000_FC_RX_PAUSE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
			 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
			else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
				 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
				 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
				 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
			{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
				hw->fc = E1000_FC_RX_PAUSE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
				e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
				    ("Flow Control = RX PAUSE frames only.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
			/* Per the IEEE spec, at this point flow control should
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
			 * be disabled.  However, we want to consider that we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
			 * could be connected to a legacy switch that doesn't
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
			 * advertise desired flow control, but can be forced on
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
			 * the link partner.  So if we advertised no flow
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
			 * control, that is what we will resolve to.  If we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
			 * advertised some kind of receive capability (Rx Pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
			 * Only or Full Flow Control) and the link partner
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
			 * advertised none, we will configure ourselves to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
			 * enable Rx Flow Control only.  We can do this safely
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
			 * for two reasons:  If the link partner really
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
			 * didn't want flow control enabled, and we enable Rx,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
			 * no harm done since we won't be receiving any PAUSE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
			 * frames anyway.  If the intent on the link partner was
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
			 * to have flow control enabled, then by us enabling Rx
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
			 * only, we can at least receive pause frames and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
			 * process them. This is a good idea because in most
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
			 * cases, since we are predominantly a server NIC, more
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
			 * times than not we will be asked to delay transmission
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
			 * of packets than asking our link partner to pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
			 * transmission of frames.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
			else if ((hw->original_fc == E1000_FC_NONE ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
				  hw->original_fc == E1000_FC_TX_PAUSE) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
				 hw->fc_strict_ieee) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
				hw->fc = E1000_FC_NONE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
				e_dbg("Flow Control = NONE.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
				hw->fc = E1000_FC_RX_PAUSE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
				e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
				    ("Flow Control = RX PAUSE frames only.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
			/* Now we need to do one last check...  If we auto-
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
			 * negotiated to HALF DUPLEX, flow control should not be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
			 * enabled per IEEE 802.3 spec.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
			if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
				e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
				    ("Error getting link speed and duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
			if (duplex == HALF_DUPLEX)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
				hw->fc = E1000_FC_NONE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
			/* Now we call a subroutine to actually force the MAC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
			 * controller to use the correct flow control settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
			ret_val = e1000_force_mac_fc(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
			if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
				e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
				    ("Error forcing flow control settings\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
			e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
			    ("Copper PHY and Auto Neg has not completed.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
 * e1000_check_for_serdes_link_generic - Check for link (Serdes)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
 * @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
 * Checks for link up on the hardware.  If link is not up and we have
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
 * a signal, then we need to force link up.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
static s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	u32 rxcw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	u32 status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	s32 ret_val = E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
	status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
	rxcw = er32(RXCW);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	/* If we don't have link (auto-negotiation failed or link partner
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
	 * cannot auto-negotiate), and our link partner is not trying to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	 * auto-negotiate with us (we are receiving idles or data),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	 * we need to force link up. We also need to give auto-negotiation
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	 * time to complete.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
		if (hw->autoneg_failed == 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
			hw->autoneg_failed = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
			goto out;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
		e_dbg("NOT RXing /C/, disable AutoNeg and force link.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
		/* Disable auto-negotiation in the TXCW register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
		ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
		/* Force link-up and also force full-duplex. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
		ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
		ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
		/* Configure Flow Control after forcing link up. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
		ret_val = e1000_config_fc_after_link_up(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
			e_dbg("Error configuring flow control\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
			goto out;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
		/* If we are forcing link and we are receiving /C/ ordered
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		 * sets, re-enable auto-negotiation in the TXCW register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		 * and disable forced link in the Device Control register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
		 * in an attempt to auto-negotiate with our link partner.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		e_dbg("RXing /C/, enable AutoNeg and stop forcing link.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
		ew32(TXCW, hw->txcw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
		hw->serdes_has_link = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		/* If we force link for non-auto-negotiation switch, check
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
		 * link status based on MAC synchronization for internal
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		 * serdes media type.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
		/* SYNCH bit and IV bit are sticky. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		udelay(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
		rxcw = er32(RXCW);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
		if (rxcw & E1000_RXCW_SYNCH) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
			if (!(rxcw & E1000_RXCW_IV)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
				hw->serdes_has_link = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
				e_dbg("SERDES: Link up - forced.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
			hw->serdes_has_link = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
			e_dbg("SERDES: Link down - force failed.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	if (E1000_TXCW_ANE & er32(TXCW)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
		status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
		if (status & E1000_STATUS_LU) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
			/* SYNCH bit and IV bit are sticky, so reread rxcw. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
			udelay(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
			rxcw = er32(RXCW);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
			if (rxcw & E1000_RXCW_SYNCH) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
				if (!(rxcw & E1000_RXCW_IV)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
					hw->serdes_has_link = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
					e_dbg("SERDES: Link up - autoneg "
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
						 "completed successfully.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
				} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
					hw->serdes_has_link = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
					e_dbg("SERDES: Link down - invalid"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
						 "codewords detected in autoneg.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
				hw->serdes_has_link = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
				e_dbg("SERDES: Link down - no sync.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
			hw->serdes_has_link = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
			e_dbg("SERDES: Link down - autoneg failed\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
      out:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
 * e1000_check_for_link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
 * Checks to see if the link status of the hardware has changed.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
 * Called by any function that needs to check the link status of the adapter.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
s32 e1000_check_for_link(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	u32 rxcw = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	u32 status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	u32 rctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
	u32 icr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
	u32 signal = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
	status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
	/* On adapters with a MAC newer than 82544, SW Definable pin 1 will be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
	 * set when the optics detect a signal. On older adapters, it will be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
	 * cleared when there is a signal.  This applies to fiber media only.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	if ((hw->media_type == e1000_media_type_fiber) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	    (hw->media_type == e1000_media_type_internal_serdes)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
		rxcw = er32(RXCW);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
		if (hw->media_type == e1000_media_type_fiber) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
			signal =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
			    (hw->mac_type >
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
			     e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
			if (status & E1000_STATUS_LU)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
				hw->get_link_status = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	/* If we have a copper PHY then we only want to go out to the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	 * registers to see if Auto-Neg has completed and/or if our link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	 * status has changed.  The get_link_status flag will be set if we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
	 * receive a Link Status Change interrupt or we have Rx Sequence
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	 * Errors.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
		/* First we want to see if the MII Status Register reports
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
		 * link.  If so, then we want to get the current speed/duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
		 * of the PHY.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
		 * Read the register twice since the link bit is sticky.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
		if (phy_data & MII_SR_LINK_STATUS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
			hw->get_link_status = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
			/* Check if there was DownShift, must be checked
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
			 * immediately after link-up
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
			e1000_check_downshift(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
			/* If we are on 82544 or 82543 silicon and speed/duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
			 * are forced to 10H or 10F, then we will implement the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
			 * polarity reversal workaround.  We disable interrupts
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
			 * first, and upon returning, place the devices
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
			 * interrupt state to its previous value except for the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
			 * link status change interrupt which will
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
			 * happen due to the execution of this workaround.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
			if ((hw->mac_type == e1000_82544
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
			     || hw->mac_type == e1000_82543) && (!hw->autoneg)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
			    && (hw->forced_speed_duplex == e1000_10_full
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
				|| hw->forced_speed_duplex == e1000_10_half)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
				ew32(IMC, 0xffffffff);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
				ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
				    e1000_polarity_reversal_workaround(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
				icr = er32(ICR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
				ew32(ICS, (icr & ~E1000_ICS_LSC));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
				ew32(IMS, IMS_ENABLE_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
			/* No link detected */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
			e1000_config_dsp_after_link_change(hw, false);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
			return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
		/* If we are forcing speed/duplex, then we simply return since
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
		 * we have already determined whether we have link or not.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
		if (!hw->autoneg)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
			return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
		/* optimize the dsp settings for the igp phy */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
		e1000_config_dsp_after_link_change(hw, true);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
		/* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
		 * have Si on board that is 82544 or newer, Auto
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		 * Speed Detection takes care of MAC speed/duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
		 * configuration.  So we only need to configure Collision
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
		 * Distance in the MAC.  Otherwise, we need to force
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
		 * speed/duplex on the MAC to the current PHY speed/duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
		 * settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		if ((hw->mac_type >= e1000_82544) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
		    (hw->mac_type != e1000_ce4100))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
			e1000_config_collision_dist(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
		else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
			ret_val = e1000_config_mac_to_phy(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
			if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
				e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
				    ("Error configuring MAC to PHY settings\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		/* Configure Flow Control now that Auto-Neg has completed.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
		 * First, we need to restore the desired flow control settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		 * because we may have had to re-autoneg with a different link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
		 * partner.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
		ret_val = e1000_config_fc_after_link_up(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
			e_dbg("Error configuring flow control\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
		/* At this point we know that we are on copper and we have
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		 * auto-negotiated link.  These are conditions for checking the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		 * link partner capability register.  We use the link speed to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
		 * determine if TBI compatibility needs to be turned on or off.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		 * If the link is not at gigabit speed, then TBI compatibility
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		 * is not needed.  If we are at gigabit speed, we turn on TBI
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
		 * compatibility.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		if (hw->tbi_compatibility_en) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
			u16 speed, duplex;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
			    e1000_get_speed_and_duplex(hw, &speed, &duplex);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
				e_dbg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
				    ("Error getting link speed and duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
			if (speed != SPEED_1000) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
				/* If link speed is not set to gigabit speed, we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
				 * do not need to enable TBI compatibility.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
				 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
				if (hw->tbi_compatibility_on) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
					/* If we previously were in the mode,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
					 * turn it off.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
					 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
					rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
					rctl &= ~E1000_RCTL_SBP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
					ew32(RCTL, rctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
					hw->tbi_compatibility_on = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
				/* If TBI compatibility is was previously off,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
				 * turn it on. For compatibility with a TBI link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
				 * partner, we will store bad packets. Some
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
				 * frames have an additional byte on the end and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
				 * will look like CRC errors to to the hardware.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
				 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
				if (!hw->tbi_compatibility_on) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
					hw->tbi_compatibility_on = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
					rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
					rctl |= E1000_RCTL_SBP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
					ew32(RCTL, rctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
	if ((hw->media_type == e1000_media_type_fiber) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
	    (hw->media_type == e1000_media_type_internal_serdes))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
		e1000_check_for_serdes_link_generic(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
 * e1000_get_speed_and_duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
 * @speed: Speed of the connection
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
 * @duplex: Duplex setting of the connection
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
 * Detects the current speed and duplex settings of the hardware.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	u32 status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	if (hw->mac_type >= e1000_82543) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
		status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
		if (status & E1000_STATUS_SPEED_1000) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
			*speed = SPEED_1000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
			e_dbg("1000 Mbs, ");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
		} else if (status & E1000_STATUS_SPEED_100) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
			*speed = SPEED_100;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
			e_dbg("100 Mbs, ");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
			*speed = SPEED_10;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
			e_dbg("10 Mbs, ");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
		if (status & E1000_STATUS_FD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
			*duplex = FULL_DUPLEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
			e_dbg("Full Duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
			*duplex = HALF_DUPLEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
			e_dbg(" Half Duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
		e_dbg("1000 Mbs, Full Duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
		*speed = SPEED_1000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
		*duplex = FULL_DUPLEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	/* IGP01 PHY may advertise full duplex operation after speed downgrade
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	 * even if it is operating at half duplex.  Here we set the duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
	 * settings to match the duplex in the link partner's capabilities.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
		ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
		if (!(phy_data & NWAY_ER_LP_NWAY_CAPS))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
			*duplex = HALF_DUPLEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
		else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
			    e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
			if ((*speed == SPEED_100
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
			     && !(phy_data & NWAY_LPAR_100TX_FD_CAPS))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
			    || (*speed == SPEED_10
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
				&& !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
				*duplex = HALF_DUPLEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
 * e1000_wait_autoneg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
 * Blocks until autoneg completes or times out (~4.5 seconds)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
static s32 e1000_wait_autoneg(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
	u16 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	e_dbg("Waiting for Auto-Neg to complete.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	/* We will wait for autoneg to complete or 4.5 seconds to expire. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
		/* Read the MII Status Register and wait for Auto-Neg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
		 * Complete bit to be set.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
		if (phy_data & MII_SR_AUTONEG_COMPLETE) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
			return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
		msleep(100);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
 * e1000_raise_mdi_clk - Raises the Management Data Clock
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
 * @ctrl: Device control register's current value
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
	/* Raise the clock input to the Management Data Clock (by setting the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
	 * MDC bit), and then delay 10 microseconds.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
	ew32(CTRL, (*ctrl | E1000_CTRL_MDC));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	udelay(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
 * e1000_lower_mdi_clk - Lowers the Management Data Clock
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
 * @ctrl: Device control register's current value
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	/* Lower the clock input to the Management Data Clock (by clearing the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	 * MDC bit), and then delay 10 microseconds.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
	ew32(CTRL, (*ctrl & ~E1000_CTRL_MDC));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
	udelay(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
 * e1000_shift_out_mdi_bits - Shifts data bits out to the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
 * @data: Data to send out to the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
 * @count: Number of bits to shift out
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
 * Bits are shifted out in MSB to LSB order.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data, u16 count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
	u32 mask;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	/* We need to shift "count" number of bits out to the PHY. So, the value
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
	 * in the "data" parameter will be shifted out to the PHY one bit at a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	 * time. In order to do this, "data" must be broken down into bits.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
	mask = 0x01;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
	mask <<= (count - 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
	/* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	while (mask) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
		/* A "1" is shifted out to the PHY by setting the MDIO bit to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
		 * "1" and then raising and lowering the Management Data Clock.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
		 * A "0" is shifted out to the PHY by setting the MDIO bit to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
		 * "0" and then raising and lowering the clock.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
		if (data & mask)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
			ctrl |= E1000_CTRL_MDIO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
			ctrl &= ~E1000_CTRL_MDIO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
		ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
		udelay(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
		e1000_raise_mdi_clk(hw, &ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
		e1000_lower_mdi_clk(hw, &ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
		mask = mask >> 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
 * e1000_shift_in_mdi_bits - Shifts data bits in from the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
 * Bits are shifted in in MSB to LSB order.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
	u16 data = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
	u8 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	/* In order to read a register from the PHY, we need to shift in a total
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
	 * of 18 bits from the PHY. The first two bit (turnaround) times are
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
	 * used to avoid contention on the MDIO pin when a read operation is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
	 * performed. These two bits are ignored by us and thrown away. Bits are
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
	 * "shifted in" by raising the input to the Management Data Clock
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
	 * (setting the MDC bit), and then reading the value of the MDIO bit.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
	/* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
	 * input.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	ctrl &= ~E1000_CTRL_MDIO_DIR;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
	ctrl &= ~E1000_CTRL_MDIO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	/* Raise and Lower the clock before reading in the data. This accounts
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	 * for the turnaround bits. The first clock occurred when we clocked out
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
	 * the last bit of the Register Address.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	e1000_raise_mdi_clk(hw, &ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	e1000_lower_mdi_clk(hw, &ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	for (data = 0, i = 0; i < 16; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
		data = data << 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
		e1000_raise_mdi_clk(hw, &ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
		ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
		/* Check to see if we shifted in a "1". */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
		if (ctrl & E1000_CTRL_MDIO)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
			data |= 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
		e1000_lower_mdi_clk(hw, &ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	e1000_raise_mdi_clk(hw, &ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
	e1000_lower_mdi_clk(hw, &ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	return data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
 * e1000_read_phy_reg - read a phy register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
 * @reg_addr: address of the PHY register to read
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
 * Reads the value from a PHY register, if the value is on a specific non zero
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
 * page, sets the page first.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	u32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	unsigned long flags;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	spin_lock_irqsave(&e1000_phy_lock, flags);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	if ((hw->phy_type == e1000_phy_igp) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
						 (u16) reg_addr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
			spin_unlock_irqrestore(&e1000_phy_lock, flags);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
	ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
					phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
	spin_unlock_irqrestore(&e1000_phy_lock, flags);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
				 u16 *phy_data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
	u32 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	u32 mdic = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
	const u32 phy_addr = (hw->mac_type == e1000_ce4100) ? hw->phy_addr : 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		e_dbg("PHY Address %d is out of range\n", reg_addr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
		return -E1000_ERR_PARAM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
	if (hw->mac_type > e1000_82543) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
		/* Set up Op-code, Phy Address, and register address in the MDI
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
		 * Control register.  The MAC will take care of interfacing with
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
		 * the PHY to retrieve the desired data.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
		if (hw->mac_type == e1000_ce4100) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
			mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
				(INTEL_CE_GBE_MDIC_OP_READ) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
				(INTEL_CE_GBE_MDIC_GO));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
			writel(mdic, E1000_MDIO_CMD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
			/* Poll the ready bit to see if the MDI read
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
			 * completed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
			for (i = 0; i < 64; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
				udelay(50);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
				mdic = readl(E1000_MDIO_CMD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
				if (!(mdic & INTEL_CE_GBE_MDIC_GO))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
					break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
			if (mdic & INTEL_CE_GBE_MDIC_GO) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
				e_dbg("MDI Read did not complete\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
				return -E1000_ERR_PHY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
			mdic = readl(E1000_MDIO_STS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
			if (mdic & INTEL_CE_GBE_MDIC_READ_ERROR) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
				e_dbg("MDI Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
				return -E1000_ERR_PHY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
			*phy_data = (u16) mdic;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
			mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
				(E1000_MDIC_OP_READ));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
			ew32(MDIC, mdic);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
			/* Poll the ready bit to see if the MDI read
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
			 * completed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
			for (i = 0; i < 64; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
				udelay(50);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
				mdic = er32(MDIC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
				if (mdic & E1000_MDIC_READY)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
					break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
			if (!(mdic & E1000_MDIC_READY)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
				e_dbg("MDI Read did not complete\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
				return -E1000_ERR_PHY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
			if (mdic & E1000_MDIC_ERROR) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
				e_dbg("MDI Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
				return -E1000_ERR_PHY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
			*phy_data = (u16) mdic;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
		/* We must first send a preamble through the MDIO pin to signal
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
		 * the beginning of an MII instruction.  This is done by sending
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
		 * 32 consecutive "1" bits.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
		/* Now combine the next few fields that are required for a read
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
		 * operation.  We use this method instead of calling the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		 * e1000_shift_out_mdi_bits routine five different times. The
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		 * format of a MII read instruction consists of a shift out of
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		 * 14 bits and is defined as follows:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		 *    <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		 * followed by a shift in of 18 bits.  This first two bits
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		 * shifted in are TurnAround bits used to avoid contention on
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		 * the MDIO pin when a READ operation is performed.  These two
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		 * bits are thrown away followed by a shift in of 16 bits which
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
		 * contains the desired data.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
		mdic = ((reg_addr) | (phy_addr << 5) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
			(PHY_OP_READ << 10) | (PHY_SOF << 12));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
		e1000_shift_out_mdi_bits(hw, mdic, 14);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		/* Now that we've shifted out the read command to the MII, we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		 * need to "shift in" the 16-bit value (18 total bits) of the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		 * requested PHY register address.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		*phy_data = e1000_shift_in_mdi_bits(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
 * e1000_write_phy_reg - write a phy register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
 * @reg_addr: address of the PHY register to write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
 * @data: data to write to the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
 * Writes a value to a PHY register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	u32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	unsigned long flags;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
	spin_lock_irqsave(&e1000_phy_lock, flags);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
	if ((hw->phy_type == e1000_phy_igp) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
	    (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
						 (u16) reg_addr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
			spin_unlock_irqrestore(&e1000_phy_lock, flags);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
	ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
					 phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	spin_unlock_irqrestore(&e1000_phy_lock, flags);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
				  u16 phy_data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
	u32 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
	u32 mdic = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
	const u32 phy_addr = (hw->mac_type == e1000_ce4100) ? hw->phy_addr : 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
	if (reg_addr > MAX_PHY_REG_ADDRESS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
		e_dbg("PHY Address %d is out of range\n", reg_addr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
		return -E1000_ERR_PARAM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
	if (hw->mac_type > e1000_82543) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
		/* Set up Op-code, Phy Address, register address, and data
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
		 * intended for the PHY register in the MDI Control register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
		 * The MAC will take care of interfacing with the PHY to send
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
		 * the desired data.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
		if (hw->mac_type == e1000_ce4100) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
			mdic = (((u32) phy_data) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
				(reg_addr << E1000_MDIC_REG_SHIFT) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
				(INTEL_CE_GBE_MDIC_OP_WRITE) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
				(INTEL_CE_GBE_MDIC_GO));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
			writel(mdic, E1000_MDIO_CMD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
			/* Poll the ready bit to see if the MDI read
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
			 * completed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
			for (i = 0; i < 640; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
				udelay(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
				mdic = readl(E1000_MDIO_CMD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
				if (!(mdic & INTEL_CE_GBE_MDIC_GO))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
					break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
			if (mdic & INTEL_CE_GBE_MDIC_GO) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
				e_dbg("MDI Write did not complete\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
				return -E1000_ERR_PHY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
			mdic = (((u32) phy_data) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
				(reg_addr << E1000_MDIC_REG_SHIFT) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
				(phy_addr << E1000_MDIC_PHY_SHIFT) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
				(E1000_MDIC_OP_WRITE));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
			ew32(MDIC, mdic);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
			/* Poll the ready bit to see if the MDI read
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
			 * completed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
			for (i = 0; i < 641; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
				udelay(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
				mdic = er32(MDIC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
				if (mdic & E1000_MDIC_READY)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
					break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
			if (!(mdic & E1000_MDIC_READY)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
				e_dbg("MDI Write did not complete\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
				return -E1000_ERR_PHY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
		/* We'll need to use the SW defined pins to shift the write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		 * command out to the PHY. We first send a preamble to the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		 * to signal the beginning of the MII instruction.  This is done
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
		 * by sending 32 consecutive "1" bits.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
		e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		/* Now combine the remaining required fields that will indicate
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
		 * a write operation. We use this method instead of calling the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
		 * e1000_shift_out_mdi_bits routine for each field in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		 * command. The format of a MII write instruction is as follows:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		 * <Preamble><SOF><OpCode><PhyAddr><RegAddr><Turnaround><Data>.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
		mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
			(PHY_OP_WRITE << 12) | (PHY_SOF << 14));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
		mdic <<= 16;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
		mdic |= (u32) phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
		e1000_shift_out_mdi_bits(hw, mdic, 32);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
 * e1000_phy_hw_reset - reset the phy, hardware style
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
 * Returns the PHY to the power-on reset state
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
s32 e1000_phy_hw_reset(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
	u32 ctrl, ctrl_ext;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
	u32 led_ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
	e_dbg("Resetting Phy...\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
	if (hw->mac_type > e1000_82543) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
		/* Read the device control register and assert the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
		 * E1000_CTRL_PHY_RST bit. Then, take it out of reset.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
		 * For e1000 hardware, we delay for 10ms between the assert
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
		 * and de-assert.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
		ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
		ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
		msleep(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
		ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		/* Read the Extended Device Control Register, assert the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
		 * PHY_RESET_DIR bit to put the PHY into reset. Then, take it
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
		 * out of reset.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
		ctrl_ext = er32(CTRL_EXT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
		ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		ew32(CTRL_EXT, ctrl_ext);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
		msleep(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
		ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
		ew32(CTRL_EXT, ctrl_ext);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
	udelay(150);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
		/* Configure activity LED after PHY reset */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
		led_ctrl = er32(LEDCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
		led_ctrl &= IGP_ACTIVITY_LED_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
		ew32(LEDCTL, led_ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	/* Wait for FW to finish PHY configuration. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
	return e1000_get_phy_cfg_done(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
 * e1000_phy_reset - reset the phy to commit settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
 * Resets the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
 * Sets bit 15 of the MII Control register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
s32 e1000_phy_reset(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	switch (hw->phy_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	case e1000_phy_igp:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
		ret_val = e1000_phy_hw_reset(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
		ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
		phy_data |= MII_CR_RESET;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
		ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		udelay(1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	if (hw->phy_type == e1000_phy_igp)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
		e1000_phy_init_script(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
 * e1000_detect_gig_phy - check the phy type
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
 * Probes the expected PHY address for known PHY IDs
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
static s32 e1000_detect_gig_phy(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
	s32 phy_init_status, ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	u16 phy_id_high, phy_id_low;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	bool match = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
	if (hw->phy_id != 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	/* Read the PHY ID Registers to identify which PHY is onboard. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
	hw->phy_id = (u32) (phy_id_high << 16);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	udelay(20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	hw->phy_id |= (u32) (phy_id_low & PHY_REVISION_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	hw->phy_revision = (u32) phy_id_low & ~PHY_REVISION_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	case e1000_82543:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
		if (hw->phy_id == M88E1000_E_PHY_ID)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
			match = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	case e1000_82544:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
		if (hw->phy_id == M88E1000_I_PHY_ID)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
			match = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	case e1000_82540:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	case e1000_82545:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	case e1000_82545_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	case e1000_82546:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	case e1000_82546_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
		if (hw->phy_id == M88E1011_I_PHY_ID)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
			match = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	case e1000_ce4100:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
		if ((hw->phy_id == RTL8211B_PHY_ID) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
		    (hw->phy_id == RTL8201N_PHY_ID) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
		    (hw->phy_id == M88E1118_E_PHY_ID))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
			match = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	case e1000_82541:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	case e1000_82541_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	case e1000_82547:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	case e1000_82547_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
		if (hw->phy_id == IGP01E1000_I_PHY_ID)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
			match = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
		e_dbg("Invalid MAC type %d\n", hw->mac_type);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
	phy_init_status = e1000_set_phy_type(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	if ((match) && (phy_init_status == E1000_SUCCESS)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
		e_dbg("PHY ID 0x%X detected\n", hw->phy_id);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
	e_dbg("Invalid PHY ID 0x%X\n", hw->phy_id);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	return -E1000_ERR_PHY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
 * e1000_phy_reset_dsp - reset DSP
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
 * Resets the PHY's DSP
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
static s32 e1000_phy_reset_dsp(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	do {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
		ret_val = e1000_write_phy_reg(hw, 29, 0x001d);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
		ret_val = e1000_write_phy_reg(hw, 30, 0x00c1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
		ret_val = e1000_write_phy_reg(hw, 30, 0x0000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
		ret_val = E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	} while (0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
 * e1000_phy_igp_get_info - get igp specific registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
 * @phy_info: PHY information structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
 * Get PHY information from various PHY registers for igp PHY only.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
				  struct e1000_phy_info *phy_info)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
	u16 phy_data, min_length, max_length, average;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	e1000_rev_polarity polarity;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	/* The downshift status is checked only once, after link is established,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
	 * and it stored in the hw->speed_downgraded parameter.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
	phy_info->downshift = (e1000_downshift) hw->speed_downgraded;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	/* IGP01E1000 does not need to support it. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
	phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
	/* IGP01E1000 always correct polarity reversal */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
	phy_info->polarity_correction = e1000_polarity_reversal_enabled;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	/* Check polarity status */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	ret_val = e1000_check_polarity(hw, &polarity);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	phy_info->cable_polarity = polarity;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	phy_info->mdix_mode =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	    (e1000_auto_x_mode) ((phy_data & IGP01E1000_PSSR_MDIX) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
				 IGP01E1000_PSSR_MDIX_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
	if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
		/* Local/Remote Receiver Information are only valid @ 1000
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
		 * Mbps
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
		phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
		/* Get cable length */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
		ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
		/* Translate to old method */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
		average = (max_length + min_length) / 2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
		if (average <= e1000_igp_cable_length_50)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
			phy_info->cable_length = e1000_cable_length_50;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
		else if (average <= e1000_igp_cable_length_80)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
			phy_info->cable_length = e1000_cable_length_50_80;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
		else if (average <= e1000_igp_cable_length_110)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
			phy_info->cable_length = e1000_cable_length_80_110;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
		else if (average <= e1000_igp_cable_length_140)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
			phy_info->cable_length = e1000_cable_length_110_140;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
			phy_info->cable_length = e1000_cable_length_140;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
 * e1000_phy_m88_get_info - get m88 specific registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
 * @phy_info: PHY information structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
 * Get PHY information from various PHY registers for m88 PHY only.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
				  struct e1000_phy_info *phy_info)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	e1000_rev_polarity polarity;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
	/* The downshift status is checked only once, after link is established,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	 * and it stored in the hw->speed_downgraded parameter.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	phy_info->downshift = (e1000_downshift) hw->speed_downgraded;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
	phy_info->extended_10bt_distance =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
	    ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
	     M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
	    e1000_10bt_ext_dist_enable_lower :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
	    e1000_10bt_ext_dist_enable_normal;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
	phy_info->polarity_correction =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	    ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
	     M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
	    e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
	/* Check polarity status */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
	ret_val = e1000_check_polarity(hw, &polarity);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
	phy_info->cable_polarity = polarity;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	phy_info->mdix_mode =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	    (e1000_auto_x_mode) ((phy_data & M88E1000_PSSR_MDIX) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
				 M88E1000_PSSR_MDIX_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
		/* Cable Length Estimation and Local/Remote Receiver Information
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
		 * are only valid at 1000 Mbps.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		phy_info->cable_length =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
		    (e1000_cable_length) ((phy_data &
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
					   M88E1000_PSSR_CABLE_LENGTH) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
					  M88E1000_PSSR_CABLE_LENGTH_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
		phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
				      SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
		phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
				       SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
		    e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
 * e1000_phy_get_info - request phy info
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
 * @phy_info: PHY information structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
 * Get PHY information from various PHY registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
s32 e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	phy_info->cable_length = e1000_cable_length_undefined;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
	phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
	phy_info->cable_polarity = e1000_rev_polarity_undefined;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
	phy_info->downshift = e1000_downshift_undefined;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
	phy_info->polarity_correction = e1000_polarity_reversal_undefined;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
	phy_info->mdix_mode = e1000_auto_x_mode_undefined;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
	phy_info->local_rx = e1000_1000t_rx_status_undefined;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
	phy_info->remote_rx = e1000_1000t_rx_status_undefined;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	if (hw->media_type != e1000_media_type_copper) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
		e_dbg("PHY info is only valid for copper media\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
	ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	if ((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
		e_dbg("PHY info is only valid if link is up\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	if (hw->phy_type == e1000_phy_igp)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		return e1000_phy_igp_get_info(hw, phy_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
	else if ((hw->phy_type == e1000_phy_8211) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	         (hw->phy_type == e1000_phy_8201))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
		return e1000_phy_m88_get_info(hw, phy_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
s32 e1000_validate_mdi_setting(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
	if (!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
		e_dbg("Invalid MDI setting detected\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
		hw->mdix = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
 * e1000_init_eeprom_params - initialize sw eeprom vars
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
 * Sets up eeprom variables in the hw struct.  Must be called after mac_type
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
 * is configured.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
s32 e1000_init_eeprom_params(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	u32 eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	s32 ret_val = E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
	u16 eeprom_size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	case e1000_82542_rev2_0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	case e1000_82542_rev2_1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	case e1000_82543:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	case e1000_82544:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
		eeprom->type = e1000_eeprom_microwire;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
		eeprom->word_size = 64;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
		eeprom->opcode_bits = 3;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
		eeprom->address_bits = 6;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
		eeprom->delay_usec = 50;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	case e1000_82540:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
	case e1000_82545:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	case e1000_82545_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	case e1000_82546:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	case e1000_82546_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
		eeprom->type = e1000_eeprom_microwire;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
		eeprom->opcode_bits = 3;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
		eeprom->delay_usec = 50;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
		if (eecd & E1000_EECD_SIZE) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
			eeprom->word_size = 256;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
			eeprom->address_bits = 8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
			eeprom->word_size = 64;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
			eeprom->address_bits = 6;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
	case e1000_82541:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
	case e1000_82541_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
	case e1000_82547:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
	case e1000_82547_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
		if (eecd & E1000_EECD_TYPE) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
			eeprom->type = e1000_eeprom_spi;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
			eeprom->opcode_bits = 8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
			eeprom->delay_usec = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
			if (eecd & E1000_EECD_ADDR_BITS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
				eeprom->page_size = 32;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
				eeprom->address_bits = 16;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
				eeprom->page_size = 8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
				eeprom->address_bits = 8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
			eeprom->type = e1000_eeprom_microwire;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
			eeprom->opcode_bits = 3;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
			eeprom->delay_usec = 50;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
			if (eecd & E1000_EECD_ADDR_BITS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
				eeprom->word_size = 256;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
				eeprom->address_bits = 8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
				eeprom->word_size = 64;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
				eeprom->address_bits = 6;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
	if (eeprom->type == e1000_eeprom_spi) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
		/* eeprom_size will be an enum [0..8] that maps to eeprom sizes
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
		 * 128B to 32KB (incremented by powers of 2).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
		/* Set to default value for initial eeprom read. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
		eeprom->word_size = 64;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
		ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
		eeprom_size =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
		    (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
		/* 256B eeprom size was not supported in earlier hardware, so we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
		 * bump eeprom_size up one to ensure that "1" (which maps to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
		 * 256B) is never the result used in the shifting logic below.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		if (eeprom_size)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
			eeprom_size++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
		eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
 * e1000_raise_ee_clk - Raises the EEPROM's clock input.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
 * @eecd: EECD's current value
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
	/* Raise the clock input to the EEPROM (by setting the SK bit), and then
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	 * wait <delay> microseconds.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
	*eecd = *eecd | E1000_EECD_SK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
	ew32(EECD, *eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
	udelay(hw->eeprom.delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
 * e1000_lower_ee_clk - Lowers the EEPROM's clock input.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
 * @eecd: EECD's current value
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
	/* Lower the clock input to the EEPROM (by clearing the SK bit), and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
	 * then wait 50 microseconds.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	*eecd = *eecd & ~E1000_EECD_SK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
	ew32(EECD, *eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
	E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
	udelay(hw->eeprom.delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
 * e1000_shift_out_ee_bits - Shift data bits out to the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
 * @data: data to send to the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
 * @count: number of bits to shift out
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data, u16 count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
	u32 eecd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
	u32 mask;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
	/* We need to shift "count" bits out to the EEPROM. So, value in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
	 * "data" parameter will be shifted out to the EEPROM one bit at a time.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
	 * In order to do this, "data" must be broken down into bits.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	mask = 0x01 << (count - 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
	eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
	if (eeprom->type == e1000_eeprom_microwire) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
		eecd &= ~E1000_EECD_DO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
	} else if (eeprom->type == e1000_eeprom_spi) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
		eecd |= E1000_EECD_DO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
	do {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
		 * "1", and then raising and then lowering the clock (the SK bit
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
		 * controls the clock input to the EEPROM).  A "0" is shifted
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
		 * out to the EEPROM by setting "DI" to "0" and then raising and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
		 * then lowering the clock.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
		eecd &= ~E1000_EECD_DI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
		if (data & mask)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
			eecd |= E1000_EECD_DI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
		udelay(eeprom->delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
		e1000_raise_ee_clk(hw, &eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
		e1000_lower_ee_clk(hw, &eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
		mask = mask >> 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	} while (mask);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	/* We leave the "DI" bit set to "0" when we leave this routine. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	eecd &= ~E1000_EECD_DI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
 * e1000_shift_in_ee_bits - Shift data bits in from the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
 * @count: number of bits to shift in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
	u32 eecd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
	u32 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
	u16 data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
	/* In order to read a register from the EEPROM, we need to shift 'count'
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
	 * bits in from the EEPROM. Bits are "shifted in" by raising the clock
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
	 * input to the EEPROM (setting the SK bit), and then reading the value
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
	 * of the "DO" bit.  During this "shifting in" process the "DI" bit
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
	 * should always be clear.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
	eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
	data = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
	for (i = 0; i < count; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
		data = data << 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
		e1000_raise_ee_clk(hw, &eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
		eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
		eecd &= ~(E1000_EECD_DI);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
		if (eecd & E1000_EECD_DO)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
			data |= 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
		e1000_lower_ee_clk(hw, &eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
	return data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
 * e1000_acquire_eeprom - Prepares EEPROM for access
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
 * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
 * function should be called before issuing a command to the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
static s32 e1000_acquire_eeprom(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	u32 eecd, i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
	eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
	/* Request EEPROM Access */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	if (hw->mac_type > e1000_82544) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
		eecd |= E1000_EECD_REQ;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
		eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
		while ((!(eecd & E1000_EECD_GNT)) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
		       (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
			i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
			udelay(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
			eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
		if (!(eecd & E1000_EECD_GNT)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
			eecd &= ~E1000_EECD_REQ;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
			ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
			e_dbg("Could not acquire EEPROM grant\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
			return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
	/* Setup EEPROM for Read/Write */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	if (eeprom->type == e1000_eeprom_microwire) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
		/* Clear SK and DI */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
		/* Set CS */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
		eecd |= E1000_EECD_CS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	} else if (eeprom->type == e1000_eeprom_spi) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
		/* Clear SK and CS */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
		udelay(1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
 * e1000_standby_eeprom - Returns EEPROM to a "standby" state
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
static void e1000_standby_eeprom(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
	u32 eecd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
	eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
	if (eeprom->type == e1000_eeprom_microwire) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
		udelay(eeprom->delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
		/* Clock high */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
		eecd |= E1000_EECD_SK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
		udelay(eeprom->delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
		/* Select EEPROM */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
		eecd |= E1000_EECD_CS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
		udelay(eeprom->delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
		/* Clock low */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
		eecd &= ~E1000_EECD_SK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
		udelay(eeprom->delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	} else if (eeprom->type == e1000_eeprom_spi) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
		/* Toggle CS to flush commands */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
		eecd |= E1000_EECD_CS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
		udelay(eeprom->delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
		eecd &= ~E1000_EECD_CS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
		udelay(eeprom->delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
 * e1000_release_eeprom - drop chip select
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
 * Terminates a command by inverting the EEPROM's chip select pin
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
static void e1000_release_eeprom(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	u32 eecd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
	eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
	if (hw->eeprom.type == e1000_eeprom_spi) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
		eecd |= E1000_EECD_CS;	/* Pull CS high */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
		eecd &= ~E1000_EECD_SK;	/* Lower SCK */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		udelay(hw->eeprom.delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
	} else if (hw->eeprom.type == e1000_eeprom_microwire) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
		/* cleanup eeprom */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
		/* CS on Microwire is active-high */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
		/* Rising edge of clock */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
		eecd |= E1000_EECD_SK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
		udelay(hw->eeprom.delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
		/* Falling edge of clock */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
		eecd &= ~E1000_EECD_SK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
		udelay(hw->eeprom.delay_usec);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
	/* Stop requesting EEPROM access */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	if (hw->mac_type > e1000_82544) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
		eecd &= ~E1000_EECD_REQ;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
		ew32(EECD, eecd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
 * e1000_spi_eeprom_ready - Reads a 16 bit word from the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
	u16 retry_count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
	u8 spi_stat_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
	/* Read "Status Register" repeatedly until the LSB is cleared.  The
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
	 * EEPROM will signal that the command has been completed by clearing
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
	 * bit 0 of the internal status register.  If it's not cleared within
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
	 * 5 milliseconds, then error out.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
	retry_count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
	do {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
		e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
					hw->eeprom.opcode_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
		spi_stat_reg = (u8) e1000_shift_in_ee_bits(hw, 8);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
		if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
		udelay(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
		retry_count += 5;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
		e1000_standby_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	} while (retry_count < EEPROM_MAX_RETRY_SPI);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
	/* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
	 * only 0-5mSec on 5V devices)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
	if (retry_count >= EEPROM_MAX_RETRY_SPI) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
		e_dbg("SPI EEPROM Status error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
		return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
 * e1000_read_eeprom - Reads a 16 bit word from the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
 * @offset: offset of  word in the EEPROM to read
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
 * @data: word read from the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
 * @words: number of words to read
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
	s32 ret;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
	spin_lock(&e1000_eeprom_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
	ret = e1000_do_read_eeprom(hw, offset, words, data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
	spin_unlock(&e1000_eeprom_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
	return ret;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
				u16 *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
	u32 i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
	if (hw->mac_type == e1000_ce4100) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
		GBE_CONFIG_FLASH_READ(GBE_CONFIG_BASE_VIRT, offset, words,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
		                      data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	/* If eeprom is not yet detected, do so now */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	if (eeprom->word_size == 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
		e1000_init_eeprom_params(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
	/* A check for invalid values:  offset too large, too many words, and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
	 * not enough words.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
	if ((offset >= eeprom->word_size)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
	    || (words > eeprom->word_size - offset) || (words == 0)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
		e_dbg("\"words\" parameter out of bounds. Words = %d,"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
		      "size = %d\n", offset, eeprom->word_size);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
		return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
	/* EEPROM's that don't use EERD to read require us to bit-bang the SPI
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
	 * directly. In this case, we need to acquire the EEPROM so that
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
	 * FW or other port software does not interrupt.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	/* Prepare the EEPROM for bit-bang reading */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
	/* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
	 * acquired the EEPROM at this point, so any returns should release it
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
	if (eeprom->type == e1000_eeprom_spi) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		u16 word_in;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
		u8 read_opcode = EEPROM_READ_OPCODE_SPI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
		if (e1000_spi_eeprom_ready(hw)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
			e1000_release_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
			return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
		e1000_standby_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
		/* Some SPI eeproms use the 8th address bit embedded in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
		 * opcode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
		if ((eeprom->address_bits == 8) && (offset >= 128))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
			read_opcode |= EEPROM_A8_OPCODE_SPI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
		/* Send the READ command (opcode + addr)  */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
		e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
		e1000_shift_out_ee_bits(hw, (u16) (offset * 2),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
					eeprom->address_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
		/* Read the data.  The address of the eeprom internally
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
		 * increments with each byte (spi) being read, saving on the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
		 * overhead of eeprom setup and tear-down.  The address counter
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
		 * will roll over if reading beyond the size of the eeprom, thus
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
		 * allowing the entire memory to be read starting from any
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
		 * offset.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
		for (i = 0; i < words; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
			word_in = e1000_shift_in_ee_bits(hw, 16);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
			data[i] = (word_in >> 8) | (word_in << 8);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
	} else if (eeprom->type == e1000_eeprom_microwire) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
		for (i = 0; i < words; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
			/* Send the READ command (opcode + addr)  */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
			e1000_shift_out_ee_bits(hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
						EEPROM_READ_OPCODE_MICROWIRE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
						eeprom->opcode_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
			e1000_shift_out_ee_bits(hw, (u16) (offset + i),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
						eeprom->address_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
			/* Read the data.  For microwire, each word requires the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
			 * overhead of eeprom setup and tear-down.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
			data[i] = e1000_shift_in_ee_bits(hw, 16);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
			e1000_standby_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
	/* End this read operation */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
	e1000_release_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
 * e1000_validate_eeprom_checksum - Verifies that the EEPROM has a valid checksum
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
 * Reads the first 64 16 bit words of the EEPROM and sums the values read.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
 * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
 * valid.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
	u16 checksum = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
	u16 i, eeprom_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
		if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
			e_dbg("EEPROM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
			return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
		checksum += eeprom_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
#ifdef CONFIG_PARISC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
	/* This is a signature and not a checksum on HP c8000 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
	if ((hw->subsystem_vendor_id == 0x103C) && (eeprom_data == 0x16d6))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
#endif
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
	if (checksum == (u16) EEPROM_SUM)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
	else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
		e_dbg("EEPROM Checksum Invalid\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
		return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
 * e1000_update_eeprom_checksum - Calculates/writes the EEPROM checksum
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
 * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
 * Writes the difference to word offset 63 of the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
s32 e1000_update_eeprom_checksum(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
	u16 checksum = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
	u16 i, eeprom_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	for (i = 0; i < EEPROM_CHECKSUM_REG; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
		if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
			e_dbg("EEPROM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
			return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
		checksum += eeprom_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
	checksum = (u16) EEPROM_SUM - checksum;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
	if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
		e_dbg("EEPROM Write Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
		return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
 * e1000_write_eeprom - write words to the different EEPROM types.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
 * @offset: offset within the EEPROM to be written to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
 * @words: number of words to write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
 * @data: 16 bit word to be written to the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
 * If e1000_update_eeprom_checksum is not called after this function, the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
 * EEPROM will most likely contain an invalid checksum.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
	s32 ret;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	spin_lock(&e1000_eeprom_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
	ret = e1000_do_write_eeprom(hw, offset, words, data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
	spin_unlock(&e1000_eeprom_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
	return ret;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
				 u16 *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
	s32 status = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
	if (hw->mac_type == e1000_ce4100) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
		GBE_CONFIG_FLASH_WRITE(GBE_CONFIG_BASE_VIRT, offset, words,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
		                       data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
	/* If eeprom is not yet detected, do so now */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	if (eeprom->word_size == 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
		e1000_init_eeprom_params(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
	/* A check for invalid values:  offset too large, too many words, and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
	 * not enough words.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
	if ((offset >= eeprom->word_size)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
	    || (words > eeprom->word_size - offset) || (words == 0)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
		e_dbg("\"words\" parameter out of bounds\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
		return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
	/* Prepare the EEPROM for writing  */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
		return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	if (eeprom->type == e1000_eeprom_microwire) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
		status = e1000_write_eeprom_microwire(hw, offset, words, data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
		status = e1000_write_eeprom_spi(hw, offset, words, data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
		msleep(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
	/* Done with writing */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
	e1000_release_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	return status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
 * e1000_write_eeprom_spi - Writes a 16 bit word to a given offset in an SPI EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
 * @offset: offset within the EEPROM to be written to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
 * @words: number of words to write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
 * @data: pointer to array of 8 bit words to be written to the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset, u16 words,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
				  u16 *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
	u16 widx = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
	while (widx < words) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
		u8 write_opcode = EEPROM_WRITE_OPCODE_SPI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
		if (e1000_spi_eeprom_ready(hw))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
			return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
		e1000_standby_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
		/*  Send the WRITE ENABLE command (8 bit opcode )  */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
		e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
					eeprom->opcode_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
		e1000_standby_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
		/* Some SPI eeproms use the 8th address bit embedded in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
		 * opcode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
		if ((eeprom->address_bits == 8) && (offset >= 128))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
			write_opcode |= EEPROM_A8_OPCODE_SPI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
		/* Send the Write command (8-bit opcode + addr) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
		e1000_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
		e1000_shift_out_ee_bits(hw, (u16) ((offset + widx) * 2),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
					eeprom->address_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
		/* Send the data */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
		/* Loop to allow for up to whole page write (32 bytes) of
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
		 * eeprom
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
		while (widx < words) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
			u16 word_out = data[widx];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
			word_out = (word_out >> 8) | (word_out << 8);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
			e1000_shift_out_ee_bits(hw, word_out, 16);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
			widx++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
			/* Some larger eeprom sizes are capable of a 32-byte
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
			 * PAGE WRITE operation, while the smaller eeproms are
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
			 * capable of an 8-byte PAGE WRITE operation.  Break the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
			 * inner loop to pass new address
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
			if ((((offset + widx) * 2) % eeprom->page_size) == 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
				e1000_standby_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
 * e1000_write_eeprom_microwire - Writes a 16 bit word to a given offset in a Microwire EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
 * @offset: offset within the EEPROM to be written to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
 * @words: number of words to write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
 * @data: pointer to array of 8 bit words to be written to the EEPROM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
					u16 words, u16 *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
	struct e1000_eeprom_info *eeprom = &hw->eeprom;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
	u32 eecd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
	u16 words_written = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
	u16 i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
	/* Send the write enable command to the EEPROM (3-bit opcode plus
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
	 * 6/8-bit dummy address beginning with 11).  It's less work to include
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
	 * the 11 of the dummy address as part of the opcode than it is to shift
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
	 * it over the correct number of bits for the address.  This puts the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
	 * EEPROM into write/erase mode.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
	e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
				(u16) (eeprom->opcode_bits + 2));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
	/* Prepare the EEPROM */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
	e1000_standby_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
	while (words_written < words) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
		/* Send the Write command (3-bit opcode + addr) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
		e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
					eeprom->opcode_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
		e1000_shift_out_ee_bits(hw, (u16) (offset + words_written),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
					eeprom->address_bits);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
		/* Send the data */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
		e1000_shift_out_ee_bits(hw, data[words_written], 16);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
		/* Toggle the CS line.  This in effect tells the EEPROM to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
		 * execute the previous command.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
		e1000_standby_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
		/* Read DO repeatedly until it is high (equal to '1').  The
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
		 * EEPROM will signal that the command has been completed by
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
		 * raising the DO signal. If DO does not go high in 10
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
		 * milliseconds, then error out.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
		for (i = 0; i < 200; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
			eecd = er32(EECD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
			if (eecd & E1000_EECD_DO)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
			udelay(50);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
		if (i == 200) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
			e_dbg("EEPROM Write did not complete\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
			return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
		/* Recover from write */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
		e1000_standby_eeprom(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
		words_written++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
	/* Send the write disable command to the EEPROM (3-bit opcode plus
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
	 * 6/8-bit dummy address beginning with 10).  It's less work to include
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
	 * the 10 of the dummy address as part of the opcode than it is to shift
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
	 * it over the correct number of bits for the address.  This takes the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
	 * EEPROM out of write/erase mode.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
	e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
				(u16) (eeprom->opcode_bits + 2));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
	e1000_shift_out_ee_bits(hw, 0, (u16) (eeprom->address_bits - 2));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
 * e1000_read_mac_addr - read the adapters MAC from eeprom
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
 * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
 * second function of dual function devices
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
s32 e1000_read_mac_addr(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
	u16 offset;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
	u16 eeprom_data, i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
	for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
		offset = i >> 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
		if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
			e_dbg("EEPROM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
			return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
		hw->perm_mac_addr[i] = (u8) (eeprom_data & 0x00FF);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
		hw->perm_mac_addr[i + 1] = (u8) (eeprom_data >> 8);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
	case e1000_82546:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
	case e1000_82546_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
			hw->perm_mac_addr[5] ^= 0x01;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
	for (i = 0; i < NODE_ADDRESS_SIZE; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
		hw->mac_addr[i] = hw->perm_mac_addr[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
 * e1000_init_rx_addrs - Initializes receive address filters.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
 * Places the MAC address in receive address register 0 and clears the rest
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
 * of the receive address registers. Clears the multicast table. Assumes
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
 * the receiver is in reset when the routine is called.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
static void e1000_init_rx_addrs(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
	u32 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
	u32 rar_num;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
	/* Setup the receive address. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
	e_dbg("Programming MAC Address into RAR[0]\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
	e1000_rar_set(hw, hw->mac_addr, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	rar_num = E1000_RAR_ENTRIES;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	/* Zero out the other 15 receive addresses. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
	e_dbg("Clearing RAR[1-15]\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	for (i = 1; i < rar_num; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
 * e1000_hash_mc_addr - Hashes an address to determine its location in the multicast table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
 * @mc_addr: the multicast address to hash
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
	u32 hash_value = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
	/* The portion of the address that is used for the hash table is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
	 * determined by the mc_filter_type setting.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	switch (hw->mc_filter_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
		/* [0] [1] [2] [3] [4] [5]
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
		 * 01  AA  00  12  34  56
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
		 * LSB                 MSB
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
	case 0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
		/* [47:36] i.e. 0x563 for above example address */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
		hash_value = ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
	case 1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		/* [46:35] i.e. 0xAC6 for above example address */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
		hash_value = ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
	case 2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
		/* [45:34] i.e. 0x5D8 for above example address */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
		hash_value = ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
	case 3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
		/* [43:32] i.e. 0x634 for above example address */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
		hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
	hash_value &= 0xFFF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	return hash_value;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
 * e1000_rar_set - Puts an ethernet address into a receive address register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
 * @addr: Address to put into receive address register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
 * @index: Receive address register to write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
	u32 rar_low, rar_high;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
	/* HW expects these in little endian so we reverse the byte order
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
	 * from network order (big endian) to little endian
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
	rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
	/* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
	 * unit hang.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	 * Description:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
	 * If there are any Rx frames queued up or otherwise present in the HW
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
	 * before RSS is enabled, and then we enable RSS, the HW Rx unit will
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
	 * hang.  To work around this issue, we have to disable receives and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
	 * flush out all Rx frames before we enable RSS. To do so, we modify we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
	 * redirect all Rx traffic to manageability and then reset the HW.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
	 * This flushes away Rx frames, and (since the redirections to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
	 * manageability persists across resets) keeps new ones from coming in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
	 * while we work.  Then, we clear the Address Valid AV bit for all MAC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
	 * addresses and undo the re-direction to manageability.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
	 * Now, frames are coming in again, but the MAC won't accept them, so
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
	 * far so good.  We now proceed to initialize RSS (if necessary) and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
	 * configure the Rx unit.  Last, we re-enable the AV bits and continue
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
	 * on our merry way.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
		/* Indicate to hardware the Address is Valid. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
		rar_high |= E1000_RAH_AV;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
	E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
	E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
 * e1000_write_vfta - Writes a value to the specified offset in the VLAN filter table.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
 * @offset: Offset in VLAN filer table to write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
 * @value: Value to write into VLAN filter table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	u32 temp;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
	if ((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
		temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
		E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
 * e1000_clear_vfta - Clears the VLAN filer table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
static void e1000_clear_vfta(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
	u32 offset;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
	u32 vfta_value = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
	u32 vfta_offset = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
	u32 vfta_bit_in_reg = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
		/* If the offset we want to clear is the same offset of the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
		 * manageability VLAN ID, then clear all bits except that of the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
		 * manageability unit
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
		vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
		E1000_WRITE_FLUSH();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
static s32 e1000_id_led_init(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
	u32 ledctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
	const u32 ledctl_mask = 0x000000FF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	u16 eeprom_data, i, temp;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	const u16 led_mask = 0x0F;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
	if (hw->mac_type < e1000_82540) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
		/* Nothing to do */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	ledctl = er32(LEDCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
	hw->ledctl_default = ledctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
	hw->ledctl_mode1 = hw->ledctl_default;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
	hw->ledctl_mode2 = hw->ledctl_default;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
	if (e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
		e_dbg("EEPROM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		return -E1000_ERR_EEPROM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
	if ((eeprom_data == ID_LED_RESERVED_0000) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
	    (eeprom_data == ID_LED_RESERVED_FFFF)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
		eeprom_data = ID_LED_DEFAULT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
	for (i = 0; i < 4; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
		temp = (eeprom_data >> (i << 2)) & led_mask;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
		switch (temp) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
		case ID_LED_ON1_DEF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
		case ID_LED_ON1_ON2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
		case ID_LED_ON1_OFF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
			hw->ledctl_mode1 |= ledctl_on << (i << 3);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
		case ID_LED_OFF1_DEF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
		case ID_LED_OFF1_ON2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
		case ID_LED_OFF1_OFF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
			hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
			hw->ledctl_mode1 |= ledctl_off << (i << 3);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
			/* Do nothing */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
		switch (temp) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
		case ID_LED_DEF1_ON2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		case ID_LED_ON1_ON2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
		case ID_LED_OFF1_ON2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
			hw->ledctl_mode2 |= ledctl_on << (i << 3);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
		case ID_LED_DEF1_OFF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
		case ID_LED_ON1_OFF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
		case ID_LED_OFF1_OFF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
			hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
			hw->ledctl_mode2 |= ledctl_off << (i << 3);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
			/* Do nothing */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
 * e1000_setup_led
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
 * Prepares SW controlable LED for use and saves the current state of the LED.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
s32 e1000_setup_led(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
	u32 ledctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
	s32 ret_val = E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	case e1000_82542_rev2_0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
	case e1000_82542_rev2_1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
	case e1000_82543:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
	case e1000_82544:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
		/* No setup necessary */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
	case e1000_82541:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
	case e1000_82547:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	case e1000_82541_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
	case e1000_82547_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
		/* Turn off PHY Smart Power Down (if enabled) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
					     &hw->phy_spd_default);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
					      (u16) (hw->phy_spd_default &
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
						     ~IGP01E1000_GMII_SPD));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
		/* Fall Through */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
		if (hw->media_type == e1000_media_type_fiber) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
			ledctl = er32(LEDCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
			/* Save current LEDCTL settings */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
			hw->ledctl_default = ledctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
			/* Turn off LED0 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
			ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
				    E1000_LEDCTL_LED0_BLINK |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
				    E1000_LEDCTL_LED0_MODE_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
			ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
				   E1000_LEDCTL_LED0_MODE_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
			ew32(LEDCTL, ledctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
		} else if (hw->media_type == e1000_media_type_copper)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
			ew32(LEDCTL, hw->ledctl_mode1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
 * e1000_cleanup_led - Restores the saved state of the SW controlable LED.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
s32 e1000_cleanup_led(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
	s32 ret_val = E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
	case e1000_82542_rev2_0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	case e1000_82542_rev2_1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	case e1000_82543:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	case e1000_82544:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
		/* No cleanup necessary */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
	case e1000_82541:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	case e1000_82547:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	case e1000_82541_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	case e1000_82547_rev_2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
		/* Turn on PHY Smart Power Down (if previously enabled) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
		ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
					      hw->phy_spd_default);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		/* Fall Through */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
		/* Restore LEDCTL settings */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
		ew32(LEDCTL, hw->ledctl_default);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
 * e1000_led_on - Turns on the software controllable LED
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
s32 e1000_led_on(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	u32 ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	case e1000_82542_rev2_0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
	case e1000_82542_rev2_1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
	case e1000_82543:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
		/* Set SW Defineable Pin 0 to turn on the LED */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
		ctrl |= E1000_CTRL_SWDPIN0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
		ctrl |= E1000_CTRL_SWDPIO0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
	case e1000_82544:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
		if (hw->media_type == e1000_media_type_fiber) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
			/* Set SW Defineable Pin 0 to turn on the LED */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
			ctrl |= E1000_CTRL_SWDPIN0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
			ctrl |= E1000_CTRL_SWDPIO0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
			/* Clear SW Defineable Pin 0 to turn on the LED */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
			ctrl &= ~E1000_CTRL_SWDPIN0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
			ctrl |= E1000_CTRL_SWDPIO0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		if (hw->media_type == e1000_media_type_fiber) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
			/* Clear SW Defineable Pin 0 to turn on the LED */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
			ctrl &= ~E1000_CTRL_SWDPIN0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
			ctrl |= E1000_CTRL_SWDPIO0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
		} else if (hw->media_type == e1000_media_type_copper) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
			ew32(LEDCTL, hw->ledctl_mode2);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
			return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
 * e1000_led_off - Turns off the software controllable LED
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
s32 e1000_led_off(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
	u32 ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
	case e1000_82542_rev2_0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
	case e1000_82542_rev2_1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
	case e1000_82543:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
		/* Clear SW Defineable Pin 0 to turn off the LED */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
		ctrl &= ~E1000_CTRL_SWDPIN0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
		ctrl |= E1000_CTRL_SWDPIO0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
	case e1000_82544:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
		if (hw->media_type == e1000_media_type_fiber) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
			/* Clear SW Defineable Pin 0 to turn off the LED */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
			ctrl &= ~E1000_CTRL_SWDPIN0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
			ctrl |= E1000_CTRL_SWDPIO0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
			/* Set SW Defineable Pin 0 to turn off the LED */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
			ctrl |= E1000_CTRL_SWDPIN0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
			ctrl |= E1000_CTRL_SWDPIO0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
		if (hw->media_type == e1000_media_type_fiber) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
			/* Set SW Defineable Pin 0 to turn off the LED */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
			ctrl |= E1000_CTRL_SWDPIN0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
			ctrl |= E1000_CTRL_SWDPIO0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
		} else if (hw->media_type == e1000_media_type_copper) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
			ew32(LEDCTL, hw->ledctl_mode1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
			return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
 * e1000_clear_hw_cntrs - Clears all hardware statistics counters.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
static void e1000_clear_hw_cntrs(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
	volatile u32 temp;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
	temp = er32(CRCERRS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
	temp = er32(SYMERRS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	temp = er32(MPC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
	temp = er32(SCC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	temp = er32(ECOL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	temp = er32(MCC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	temp = er32(LATECOL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	temp = er32(COLC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	temp = er32(DC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	temp = er32(SEC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	temp = er32(RLEC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	temp = er32(XONRXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
	temp = er32(XONTXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
	temp = er32(XOFFRXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	temp = er32(XOFFTXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	temp = er32(FCRUC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
	temp = er32(PRC64);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
	temp = er32(PRC127);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
	temp = er32(PRC255);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
	temp = er32(PRC511);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	temp = er32(PRC1023);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
	temp = er32(PRC1522);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
	temp = er32(GPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
	temp = er32(BPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
	temp = er32(MPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	temp = er32(GPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
	temp = er32(GORCL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	temp = er32(GORCH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	temp = er32(GOTCL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
	temp = er32(GOTCH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
	temp = er32(RNBC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	temp = er32(RUC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
	temp = er32(RFC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
	temp = er32(ROC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	temp = er32(RJC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
	temp = er32(TORL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	temp = er32(TORH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	temp = er32(TOTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	temp = er32(TOTH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	temp = er32(TPR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	temp = er32(TPT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	temp = er32(PTC64);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	temp = er32(PTC127);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	temp = er32(PTC255);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	temp = er32(PTC511);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	temp = er32(PTC1023);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
	temp = er32(PTC1522);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
	temp = er32(MPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
	temp = er32(BPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
	if (hw->mac_type < e1000_82543)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
	temp = er32(ALGNERRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
	temp = er32(RXERRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
	temp = er32(TNCRS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
	temp = er32(CEXTERR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
	temp = er32(TSCTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	temp = er32(TSCTFC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
	if (hw->mac_type <= e1000_82544)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
	temp = er32(MGTPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	temp = er32(MGTPDC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	temp = er32(MGTPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
 * e1000_reset_adaptive - Resets Adaptive IFS to its default state.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
 * Call this after e1000_init_hw. You may override the IFS defaults by setting
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
 * hw->ifs_params_forced to true. However, you must initialize hw->
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
 * current_ifs_val, ifs_min_val, ifs_max_val, ifs_step_size, and ifs_ratio
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
 * before calling this function.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
void e1000_reset_adaptive(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
	if (hw->adaptive_ifs) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
		if (!hw->ifs_params_forced) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
			hw->current_ifs_val = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
			hw->ifs_min_val = IFS_MIN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
			hw->ifs_max_val = IFS_MAX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
			hw->ifs_step_size = IFS_STEP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
			hw->ifs_ratio = IFS_RATIO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
		hw->in_ifs_mode = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
		ew32(AIT, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
		e_dbg("Not in Adaptive IFS mode!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
 * e1000_update_adaptive - update adaptive IFS
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
 * @tx_packets: Number of transmits since last callback
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
 * @total_collisions: Number of collisions since last callback
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
 * Called during the callback/watchdog routine to update IFS value based on
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
 * the ratio of transmits to collisions.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
void e1000_update_adaptive(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
	if (hw->adaptive_ifs) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
		if ((hw->collision_delta *hw->ifs_ratio) > hw->tx_packet_delta) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
			if (hw->tx_packet_delta > MIN_NUM_XMITS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
				hw->in_ifs_mode = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
				if (hw->current_ifs_val < hw->ifs_max_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
					if (hw->current_ifs_val == 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
						hw->current_ifs_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
						    hw->ifs_min_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
					else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
						hw->current_ifs_val +=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
						    hw->ifs_step_size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
					ew32(AIT, hw->current_ifs_val);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
			if (hw->in_ifs_mode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
			    && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
				hw->current_ifs_val = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
				hw->in_ifs_mode = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
				ew32(AIT, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
		e_dbg("Not in Adaptive IFS mode!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
 * e1000_tbi_adjust_stats
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
 * @frame_len: The length of the frame in question
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
 * @mac_addr: The Ethernet destination address of the frame in question
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
 * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
			    u32 frame_len, u8 *mac_addr)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
	u64 carry_bit;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
	/* First adjust the frame length. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
	frame_len--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
	/* We need to adjust the statistics counters, since the hardware
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
	 * counters overcount this packet as a CRC error and undercount
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
	 * the packet as a good packet
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
	/* This packet should not be counted as a CRC error. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
	stats->crcerrs--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
	/* This packet does count as a Good Packet Received. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
	stats->gprc++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
	/* Adjust the Good Octets received counters */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
	carry_bit = 0x80000000 & stats->gorcl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
	stats->gorcl += frame_len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
	/* If the high bit of Gorcl (the low 32 bits of the Good Octets
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
	 * Received Count) was one before the addition,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
	 * AND it is zero after, then we lost the carry out,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
	 * need to add one to Gorch (Good Octets Received Count High).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
	 * This could be simplified if all environments supported
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
	 * 64-bit integers.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
	if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
		stats->gorch++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
	/* Is this a broadcast or multicast?  Check broadcast first,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
	 * since the test for a multicast frame will test positive on
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
	 * a broadcast frame.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
	if (is_broadcast_ether_addr(mac_addr))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
		/* Broadcast packet */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
		stats->bprc++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
	else if (is_multicast_ether_addr(mac_addr))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
		/* Multicast packet */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
		stats->mprc++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
	if (frame_len == hw->max_frame_size) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
		/* In this case, the hardware has overcounted the number of
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
		 * oversize frames.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
		if (stats->roc > 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
			stats->roc--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
	/* Adjust the bin counters when the extra byte put the frame in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
	 * wrong bin. Remember that the frame_len was adjusted above.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
	if (frame_len == 64) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
		stats->prc64++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
		stats->prc127--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
	} else if (frame_len == 127) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
		stats->prc127++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
		stats->prc255--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
	} else if (frame_len == 255) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
		stats->prc255++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
		stats->prc511--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
	} else if (frame_len == 511) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
		stats->prc511++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
		stats->prc1023--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
	} else if (frame_len == 1023) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
		stats->prc1023++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
		stats->prc1522--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
	} else if (frame_len == 1522) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
		stats->prc1522++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
 * e1000_get_bus_info
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
 * Gets the current PCI bus type, speed, and width of the hardware
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
void e1000_get_bus_info(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
	u32 status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
	case e1000_82542_rev2_0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
	case e1000_82542_rev2_1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
		hw->bus_type = e1000_bus_type_pci;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
		hw->bus_speed = e1000_bus_speed_unknown;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
		hw->bus_width = e1000_bus_width_unknown;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
		status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
		hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
		    e1000_bus_type_pcix : e1000_bus_type_pci;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
		if (hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
			hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
			    e1000_bus_speed_66 : e1000_bus_speed_120;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
		} else if (hw->bus_type == e1000_bus_type_pci) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
			hw->bus_speed = (status & E1000_STATUS_PCI66) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
			    e1000_bus_speed_66 : e1000_bus_speed_33;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
			switch (status & E1000_STATUS_PCIX_SPEED) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
			case E1000_STATUS_PCIX_SPEED_66:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
				hw->bus_speed = e1000_bus_speed_66;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
			case E1000_STATUS_PCIX_SPEED_100:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
				hw->bus_speed = e1000_bus_speed_100;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
			case E1000_STATUS_PCIX_SPEED_133:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
				hw->bus_speed = e1000_bus_speed_133;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
			default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
				hw->bus_speed = e1000_bus_speed_reserved;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
		hw->bus_width = (status & E1000_STATUS_BUS64) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
		    e1000_bus_width_64 : e1000_bus_width_32;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
 * e1000_write_reg_io
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
 * @offset: offset to write to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
 * @value: value to write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
 * Writes a value to one of the devices registers using port I/O (as opposed to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
 * memory mapped I/O). Only 82544 and newer devices support port I/O.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
	unsigned long io_addr = hw->io_base;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
	unsigned long io_data = hw->io_base + 4;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
	e1000_io_write(hw, io_addr, offset);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
	e1000_io_write(hw, io_data, value);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
 * e1000_get_cable_length - Estimates the cable length.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
 * @min_length: The estimated minimum length
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
 * @max_length: The estimated maximum length
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
 * returns: - E1000_ERR_XXX
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
 *            E1000_SUCCESS
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
 * This function always returns a ranged length (minimum & maximum).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
 * So for M88 phy's, this function interprets the one value returned from the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
 * register to the minimum and maximum range.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
 * For IGP phy's, the function calculates the range by the AGC registers.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
				  u16 *max_length)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
	u16 agc_value = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
	u16 i, phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
	u16 cable_length;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
	*min_length = *max_length = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
	/* Use old method for Phy older than IGP */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
	if (hw->phy_type == e1000_phy_m88) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
					     &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
		cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
		    M88E1000_PSSR_CABLE_LENGTH_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
		/* Convert the enum value to ranged values */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
		switch (cable_length) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
		case e1000_cable_length_50:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
			*min_length = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
			*max_length = e1000_igp_cable_length_50;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
		case e1000_cable_length_50_80:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
			*min_length = e1000_igp_cable_length_50;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
			*max_length = e1000_igp_cable_length_80;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
		case e1000_cable_length_80_110:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
			*min_length = e1000_igp_cable_length_80;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
			*max_length = e1000_igp_cable_length_110;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
		case e1000_cable_length_110_140:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
			*min_length = e1000_igp_cable_length_110;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
			*max_length = e1000_igp_cable_length_140;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
		case e1000_cable_length_140:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
			*min_length = e1000_igp_cable_length_140;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
			*max_length = e1000_igp_cable_length_170;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
			return -E1000_ERR_PHY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
	} else if (hw->phy_type == e1000_phy_igp) {	/* For IGP PHY */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
		u16 cur_agc_value;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
		u16 min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
		static const u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
		       IGP01E1000_PHY_AGC_A,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
		       IGP01E1000_PHY_AGC_B,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
		       IGP01E1000_PHY_AGC_C,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
		       IGP01E1000_PHY_AGC_D
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
		};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
		/* Read the AGC registers for all channels */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
		for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
			    e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
			cur_agc_value = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
			/* Value bound check. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
			if ((cur_agc_value >=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
			     IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
			    || (cur_agc_value == 0))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
				return -E1000_ERR_PHY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
			agc_value += cur_agc_value;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
			/* Update minimal AGC value. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
			if (min_agc_value > cur_agc_value)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
				min_agc_value = cur_agc_value;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
		/* Remove the minimal AGC result for length < 50m */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
		if (agc_value <
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
		    IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
			agc_value -= min_agc_value;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
			/* Get the average length of the remaining 3 channels */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
			agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
			/* Get the average length of all the 4 channels. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
			agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
		/* Set the range of the calculated length. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
		*min_length = ((e1000_igp_cable_length_table[agc_value] -
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
				IGP01E1000_AGC_RANGE) > 0) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
		    (e1000_igp_cable_length_table[agc_value] -
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
		     IGP01E1000_AGC_RANGE) : 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
		*max_length = e1000_igp_cable_length_table[agc_value] +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
		    IGP01E1000_AGC_RANGE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
 * e1000_check_polarity - Check the cable polarity
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
 * @polarity: output parameter : 0 - Polarity is not reversed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
 *                               1 - Polarity is reversed.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
 * returns: - E1000_ERR_XXX
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
 *            E1000_SUCCESS
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
 * For phy's older than IGP, this function simply reads the polarity bit in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
 * Phy Status register.  For IGP phy's, this bit is valid only if link speed is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
 * 10 Mbps.  If the link speed is 100 Mbps there is no polarity so this bit will
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
 * return 0.  If the link speed is 1000 Mbps the polarity status is in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
 * IGP01E1000_PHY_PCS_INIT_REG.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
static s32 e1000_check_polarity(struct e1000_hw *hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
				e1000_rev_polarity *polarity)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
	if (hw->phy_type == e1000_phy_m88) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
		/* return the Polarity bit in the Status register. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
					     &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
		*polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
			     M88E1000_PSSR_REV_POLARITY_SHIFT) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
		    e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
	} else if (hw->phy_type == e1000_phy_igp) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
		/* Read the Status register to check the speed */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
					     &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
		/* If speed is 1000 Mbps, must read the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
		 * IGP01E1000_PHY_PCS_INIT_REG to find the polarity status
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
		if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
		    IGP01E1000_PSSR_SPEED_1000MBPS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
			/* Read the GIG initialization PCS register (0x00B4) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
					       &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
			/* Check the polarity bits */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
			*polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
			    e1000_rev_polarity_reversed :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
			    e1000_rev_polarity_normal;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
			/* For 10 Mbps, read the polarity bit in the status
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
			 * register. (for 100 Mbps this bit is always 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
			*polarity =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
			    (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
			    e1000_rev_polarity_reversed :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
			    e1000_rev_polarity_normal;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
 * e1000_check_downshift - Check if Downshift occurred
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
 * @downshift: output parameter : 0 - No Downshift occurred.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
 *                                1 - Downshift occurred.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
 * returns: - E1000_ERR_XXX
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
 *            E1000_SUCCESS
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
 * For phy's older than IGP, this function reads the Downshift bit in the Phy
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
 * Specific Status register.  For IGP phy's, it reads the Downgrade bit in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
 * Link Health register.  In IGP this bit is latched high, so the driver must
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
 * read it immediately after link is established.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
static s32 e1000_check_downshift(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
	if (hw->phy_type == e1000_phy_igp) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
					     &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
		hw->speed_downgraded =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
		    (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
	} else if (hw->phy_type == e1000_phy_m88) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
					     &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
		hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
		    M88E1000_PSSR_DOWNSHIFT_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
static const u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
	IGP01E1000_PHY_AGC_PARAM_A,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
	IGP01E1000_PHY_AGC_PARAM_B,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
	IGP01E1000_PHY_AGC_PARAM_C,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
	IGP01E1000_PHY_AGC_PARAM_D
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
static s32 e1000_1000Mb_check_cable_length(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
	u16 min_length, max_length;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
	u16 phy_data, i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
	ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
	if (hw->dsp_config_state != e1000_dsp_config_enabled)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
	if (min_length >= e1000_igp_cable_length_50) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
		for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
			ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
						     &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
			phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
			ret_val = e1000_write_phy_reg(hw, dsp_reg_array[i],
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
						      phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
		hw->dsp_config_state = e1000_dsp_config_activated;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
		u16 ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
		u32 idle_errs = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
		/* clear previous idle error counts */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
		ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
		for (i = 0; i < ffe_idle_err_timeout; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
			udelay(1000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
			ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
						     &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
			idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
			if (idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
				hw->ffe_config_state = e1000_ffe_config_active;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
				ret_val = e1000_write_phy_reg(hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
					      IGP01E1000_PHY_DSP_FFE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
					      IGP01E1000_PHY_DSP_FFE_CM_CP);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
				if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
					return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
			if (idle_errs)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
				ffe_idle_err_timeout =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
					    FFE_IDLE_ERR_COUNT_TIMEOUT_100;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
 * e1000_config_dsp_after_link_change
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
 * @link_up: was link up at the time this was called
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
 *            E1000_SUCCESS at any other case.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
 * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
 * gigabit link is achieved to improve link quality.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw, bool link_up)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
	u16 phy_data, phy_saved_data, speed, duplex, i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
	if (hw->phy_type != e1000_phy_igp)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
	if (link_up) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
		ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
			e_dbg("Error getting link speed and duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
		if (speed == SPEED_1000) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
			ret_val = e1000_1000Mb_check_cable_length(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
		if (hw->dsp_config_state == e1000_dsp_config_activated) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
			/* Save off the current value of register 0x2F5B to be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
			 * restored at the end of the routines.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
			    e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
			/* Disable the PHY transmitter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
			ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
			msleep(20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
			ret_val = e1000_write_phy_reg(hw, 0x0000,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
						    IGP01E1000_IEEE_FORCE_GIGA);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
			for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
				ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
				    e1000_read_phy_reg(hw, dsp_reg_array[i],
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
						       &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
				if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
					return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
				phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
				phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
				ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
				    e1000_write_phy_reg(hw, dsp_reg_array[i],
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
							phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
				if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
					return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
			ret_val = e1000_write_phy_reg(hw, 0x0000,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
					IGP01E1000_IEEE_RESTART_AUTONEG);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
			msleep(20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
			/* Now enable the transmitter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
			    e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
			hw->dsp_config_state = e1000_dsp_config_enabled;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
		if (hw->ffe_config_state == e1000_ffe_config_active) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
			/* Save off the current value of register 0x2F5B to be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
			 * restored at the end of the routines.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
			    e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
			/* Disable the PHY transmitter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
			ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
			msleep(20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
			ret_val = e1000_write_phy_reg(hw, 0x0000,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
						    IGP01E1000_IEEE_FORCE_GIGA);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
						IGP01E1000_PHY_DSP_FFE_DEFAULT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
			ret_val = e1000_write_phy_reg(hw, 0x0000,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
					IGP01E1000_IEEE_RESTART_AUTONEG);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
			msleep(20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
			/* Now enable the transmitter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
			    e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
			hw->ffe_config_state = e1000_ffe_config_enabled;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
 * e1000_set_phy_mode - Set PHY to class A mode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
 * Assumes the following operations will follow to enable the new class mode.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
 *  1. Do a PHY soft reset
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
 *  2. Restart auto-negotiation or force link.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
static s32 e1000_set_phy_mode(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
	u16 eeprom_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
	if ((hw->mac_type == e1000_82545_rev_3) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
	    (hw->media_type == e1000_media_type_copper)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
		    e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
				      &eeprom_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
		if ((eeprom_data != EEPROM_RESERVED_WORD) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
		    (eeprom_data & EEPROM_PHY_CLASS_A)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
			    e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
						0x000B);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
			    e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
						0x8104);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
			hw->phy_reset_disable = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
 * e1000_set_d3_lplu_state - set d3 link power state
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
 * @active: true to enable lplu false to disable lplu.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
 * This function sets the lplu state according to the active flag.  When
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
 * activating lplu this function also disables smart speed and vise versa.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
 * lplu will not be activated unless the device autonegotiation advertisement
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
 * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
 * returns: - E1000_ERR_PHY if fail to read/write the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
 *            E1000_SUCCESS at any other case.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
	if (hw->phy_type != e1000_phy_igp)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
	/* During driver activity LPLU should not be used or it will attain link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
	 * from the lowest speeds starting from 10Mbps. The capability is used
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
	 * for Dx transitions and states
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
	if (hw->mac_type == e1000_82541_rev_2
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
	    || hw->mac_type == e1000_82547_rev_2) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
		    e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
	if (!active) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
		if (hw->mac_type == e1000_82541_rev_2 ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
		    hw->mac_type == e1000_82547_rev_2) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
			phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
			    e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
						phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
		 * during Dx states where the power conservation is most
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
		 * important.  During driver activity we should enable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
		 * SmartSpeed, so performance is maintained.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
		if (hw->smart_speed == e1000_smart_speed_on) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
					       &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
			phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
						phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
		} else if (hw->smart_speed == e1000_smart_speed_off) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
			    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
					       &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
			    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
						phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
	} else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
		   || (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
		   || (hw->autoneg_advertised ==
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
		       AUTONEG_ADVERTISE_10_100_ALL)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
		if (hw->mac_type == e1000_82541_rev_2 ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
		    hw->mac_type == e1000_82547_rev_2) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
			phy_data |= IGP01E1000_GMII_FLEX_SPD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
			ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
			    e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
						phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
			if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
				return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
		/* When LPLU is enabled we should disable SmartSpeed */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
		    e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
				       &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
		phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
		ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
		    e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
					phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
 * e1000_set_vco_speed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
 * Change VCO speed register to improve Bit Error Rate performance of SERDES.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
static s32 e1000_set_vco_speed(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
	u16 default_page = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
	switch (hw->mac_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
	case e1000_82545_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
	case e1000_82546_rev_3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
		return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
	/* Set PHY register 30, page 5, bit 8 to 0 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
	ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
	    e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
	phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
	/* Set PHY register 30, page 4, bit 11 to 1 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
	phy_data |= M88E1000_PHY_VCO_REG_BIT11;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
	ret_val =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
	    e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5635
 * e1000_enable_mng_pass_thru - check for bmc pass through
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5636
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5637
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5638
 * Verifies the hardware needs to allow ARPs to be processed by the host
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5639
 * returns: - true/false
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5640
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5641
u32 e1000_enable_mng_pass_thru(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5642
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5643
	u32 manc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5644
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5645
	if (hw->asf_firmware_present) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5646
		manc = er32(MANC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5647
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5648
		if (!(manc & E1000_MANC_RCV_TCO_EN) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5649
		    !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5650
			return false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5651
		if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5652
			return true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5653
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5654
	return false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5655
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5656
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5657
static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5658
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5659
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5660
	u16 mii_status_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5661
	u16 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5662
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5663
	/* Polarity reversal workaround for forced 10F/10H links. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5664
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5665
	/* Disable the transmitter on the PHY */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5666
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5667
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5668
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5669
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5670
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5671
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5672
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5673
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5674
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5675
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5676
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5677
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5678
	/* This loop will early-out if the NO link condition has been met. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5679
	for (i = PHY_FORCE_TIME; i > 0; i--) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5680
		/* Read the MII Status Register and wait for Link Status bit
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5681
		 * to be clear.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5682
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5683
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5684
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5685
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5686
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5687
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5688
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5689
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5690
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5691
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5692
		if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5693
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5694
		msleep(100);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5695
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5696
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5697
	/* Recommended delay time after link has been lost */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5698
	msleep(1000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5699
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5700
	/* Now we will re-enable th transmitter on the PHY */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5701
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5702
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5703
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5704
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5705
	msleep(50);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5706
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5707
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5708
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5709
	msleep(50);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5710
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5711
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5712
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5713
	msleep(50);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5714
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5715
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5716
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5717
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5718
	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5719
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5720
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5721
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5722
	/* This loop will early-out if the link condition has been met. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5723
	for (i = PHY_FORCE_TIME; i > 0; i--) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5724
		/* Read the MII Status Register and wait for Link Status bit
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5725
		 * to be set.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5726
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5727
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5728
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5729
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5730
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5731
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5732
		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5733
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5734
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5735
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5736
		if (mii_status_reg & MII_SR_LINK_STATUS)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5737
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5738
		msleep(100);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5739
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5740
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5741
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5742
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5743
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5744
 * e1000_get_auto_rd_done
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5745
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5746
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5747
 * Check for EEPROM Auto Read bit done.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5748
 * returns: - E1000_ERR_RESET if fail to reset MAC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5749
 *            E1000_SUCCESS at any other case.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5750
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5751
static s32 e1000_get_auto_rd_done(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5752
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5753
	msleep(5);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5754
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5755
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5756
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5757
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5758
 * e1000_get_phy_cfg_done
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5759
 * @hw: Struct containing variables accessed by shared code
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5760
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5761
 * Checks if the PHY configuration is done
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5762
 * returns: - E1000_ERR_RESET if fail to reset MAC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5763
 *            E1000_SUCCESS at any other case.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5764
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5765
static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5766
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5767
	msleep(10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5768
	return E1000_SUCCESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5769
}