devices/igb/e1000_phy-3.18-ethercat.c
author Florian Pose <fp@igh.de>
Fri, 27 Oct 2017 12:18:11 +0200
branchstable-1.5
changeset 2690 d984f57bef97
parent 2685 740291442c05
permissions -rw-r--r--
Mention igb driver in config files.
2685
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
     1
/* Intel(R) Gigabit Ethernet Linux driver
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
     2
 * Copyright(c) 2007-2014 Intel Corporation.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
     3
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
     4
 * This program is free software; you can redistribute it and/or modify it
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
     5
 * under the terms and conditions of the GNU General Public License,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
     6
 * version 2, as published by the Free Software Foundation.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
     7
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
     8
 * This program is distributed in the hope it will be useful, but WITHOUT
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
     9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    10
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    11
 * more details.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    12
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    13
 * You should have received a copy of the GNU General Public License along with
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    14
 * this program; if not, see <http://www.gnu.org/licenses/>.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    15
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    16
 * The full GNU General Public License is included in this distribution in
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    17
 * the file called "COPYING".
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    18
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    19
 * Contact Information:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    20
 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    21
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    22
 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    23
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    24
#include <linux/if_ether.h>
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    25
#include <linux/delay.h>
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    26
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    27
#include "e1000_mac-3.18-ethercat.h"
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    28
#include "e1000_phy-3.18-ethercat.h"
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    29
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    30
static s32  igb_phy_setup_autoneg(struct e1000_hw *hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    31
static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    32
					     u16 *phy_ctrl);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    33
static s32  igb_wait_autoneg(struct e1000_hw *hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    34
static s32  igb_set_master_slave_mode(struct e1000_hw *hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    35
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    36
/* Cable length tables */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    37
static const u16 e1000_m88_cable_length_table[] = {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    38
	0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    39
#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    40
	(sizeof(e1000_m88_cable_length_table) / \
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    41
	sizeof(e1000_m88_cable_length_table[0]))
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    42
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    43
static const u16 e1000_igp_2_cable_length_table[] = {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    44
	0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    45
	0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    46
	6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    47
	21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    48
	40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    49
	60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    50
	83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    51
	104, 109, 114, 118, 121, 124};
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    52
#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    53
	(sizeof(e1000_igp_2_cable_length_table) / \
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    54
	 sizeof(e1000_igp_2_cable_length_table[0]))
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    55
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    56
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    57
 *  igb_check_reset_block - Check if PHY reset is blocked
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    58
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    59
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    60
 *  Read the PHY management control register and check whether a PHY reset
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    61
 *  is blocked.  If a reset is not blocked return 0, otherwise
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    62
 *  return E1000_BLK_PHY_RESET (12).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    63
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    64
s32 igb_check_reset_block(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    65
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    66
	u32 manc;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    67
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    68
	manc = rd32(E1000_MANC);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    69
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    70
	return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? E1000_BLK_PHY_RESET : 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    71
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    72
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    73
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    74
 *  igb_get_phy_id - Retrieve the PHY ID and revision
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    75
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    76
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    77
 *  Reads the PHY registers and stores the PHY ID and possibly the PHY
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    78
 *  revision in the hardware structure.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    79
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    80
s32 igb_get_phy_id(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    81
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    82
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    83
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    84
	u16 phy_id;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    85
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    86
	ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    87
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    88
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    89
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    90
	phy->id = (u32)(phy_id << 16);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    91
	udelay(20);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    92
	ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    93
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    94
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    95
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    96
	phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    97
	phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    98
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
    99
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   100
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   101
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   102
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   103
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   104
 *  igb_phy_reset_dsp - Reset PHY DSP
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   105
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   106
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   107
 *  Reset the digital signal processor.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   108
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   109
static s32 igb_phy_reset_dsp(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   110
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   111
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   112
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   113
	if (!(hw->phy.ops.write_reg))
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   114
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   115
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   116
	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   117
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   118
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   119
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   120
	ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   121
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   122
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   123
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   124
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   125
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   126
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   127
 *  igb_read_phy_reg_mdic - Read MDI control register
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   128
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   129
 *  @offset: register offset to be read
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   130
 *  @data: pointer to the read data
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   131
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   132
 *  Reads the MDI control regsiter in the PHY at offset and stores the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   133
 *  information read to data.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   134
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   135
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   136
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   137
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   138
	u32 i, mdic = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   139
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   140
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   141
	if (offset > MAX_PHY_REG_ADDRESS) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   142
		hw_dbg("PHY Address %d is out of range\n", offset);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   143
		ret_val = -E1000_ERR_PARAM;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   144
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   145
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   146
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   147
	/* Set up Op-code, Phy Address, and register offset in the MDI
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   148
	 * Control register.  The MAC will take care of interfacing with the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   149
	 * PHY to retrieve the desired data.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   150
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   151
	mdic = ((offset << E1000_MDIC_REG_SHIFT) |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   152
		(phy->addr << E1000_MDIC_PHY_SHIFT) |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   153
		(E1000_MDIC_OP_READ));
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   154
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   155
	wr32(E1000_MDIC, mdic);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   156
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   157
	/* Poll the ready bit to see if the MDI read completed
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   158
	 * Increasing the time out as testing showed failures with
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   159
	 * the lower time out
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   160
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   161
	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   162
		udelay(50);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   163
		mdic = rd32(E1000_MDIC);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   164
		if (mdic & E1000_MDIC_READY)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   165
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   166
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   167
	if (!(mdic & E1000_MDIC_READY)) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   168
		hw_dbg("MDI Read did not complete\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   169
		ret_val = -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   170
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   171
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   172
	if (mdic & E1000_MDIC_ERROR) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   173
		hw_dbg("MDI Error\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   174
		ret_val = -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   175
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   176
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   177
	*data = (u16) mdic;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   178
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   179
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   180
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   181
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   182
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   183
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   184
 *  igb_write_phy_reg_mdic - Write MDI control register
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   185
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   186
 *  @offset: register offset to write to
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   187
 *  @data: data to write to register at offset
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   188
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   189
 *  Writes data to MDI control register in the PHY at offset.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   190
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   191
s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   192
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   193
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   194
	u32 i, mdic = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   195
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   196
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   197
	if (offset > MAX_PHY_REG_ADDRESS) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   198
		hw_dbg("PHY Address %d is out of range\n", offset);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   199
		ret_val = -E1000_ERR_PARAM;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   200
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   201
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   202
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   203
	/* Set up Op-code, Phy Address, and register offset in the MDI
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   204
	 * Control register.  The MAC will take care of interfacing with the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   205
	 * PHY to retrieve the desired data.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   206
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   207
	mdic = (((u32)data) |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   208
		(offset << E1000_MDIC_REG_SHIFT) |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   209
		(phy->addr << E1000_MDIC_PHY_SHIFT) |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   210
		(E1000_MDIC_OP_WRITE));
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   211
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   212
	wr32(E1000_MDIC, mdic);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   213
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   214
	/* Poll the ready bit to see if the MDI read completed
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   215
	 * Increasing the time out as testing showed failures with
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   216
	 * the lower time out
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   217
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   218
	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   219
		udelay(50);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   220
		mdic = rd32(E1000_MDIC);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   221
		if (mdic & E1000_MDIC_READY)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   222
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   223
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   224
	if (!(mdic & E1000_MDIC_READY)) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   225
		hw_dbg("MDI Write did not complete\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   226
		ret_val = -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   227
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   228
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   229
	if (mdic & E1000_MDIC_ERROR) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   230
		hw_dbg("MDI Error\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   231
		ret_val = -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   232
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   233
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   234
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   235
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   236
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   237
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   238
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   239
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   240
 *  igb_read_phy_reg_i2c - Read PHY register using i2c
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   241
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   242
 *  @offset: register offset to be read
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   243
 *  @data: pointer to the read data
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   244
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   245
 *  Reads the PHY register at offset using the i2c interface and stores the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   246
 *  retrieved information in data.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   247
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   248
s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   249
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   250
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   251
	u32 i, i2ccmd = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   252
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   253
	/* Set up Op-code, Phy Address, and register address in the I2CCMD
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   254
	 * register.  The MAC will take care of interfacing with the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   255
	 * PHY to retrieve the desired data.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   256
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   257
	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   258
		  (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   259
		  (E1000_I2CCMD_OPCODE_READ));
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   260
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   261
	wr32(E1000_I2CCMD, i2ccmd);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   262
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   263
	/* Poll the ready bit to see if the I2C read completed */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   264
	for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   265
		udelay(50);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   266
		i2ccmd = rd32(E1000_I2CCMD);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   267
		if (i2ccmd & E1000_I2CCMD_READY)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   268
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   269
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   270
	if (!(i2ccmd & E1000_I2CCMD_READY)) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   271
		hw_dbg("I2CCMD Read did not complete\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   272
		return -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   273
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   274
	if (i2ccmd & E1000_I2CCMD_ERROR) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   275
		hw_dbg("I2CCMD Error bit set\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   276
		return -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   277
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   278
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   279
	/* Need to byte-swap the 16-bit value. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   280
	*data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   281
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   282
	return 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   283
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   284
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   285
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   286
 *  igb_write_phy_reg_i2c - Write PHY register using i2c
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   287
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   288
 *  @offset: register offset to write to
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   289
 *  @data: data to write at register offset
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   290
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   291
 *  Writes the data to PHY register at the offset using the i2c interface.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   292
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   293
s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   294
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   295
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   296
	u32 i, i2ccmd = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   297
	u16 phy_data_swapped;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   298
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   299
	/* Prevent overwritting SFP I2C EEPROM which is at A0 address.*/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   300
	if ((hw->phy.addr == 0) || (hw->phy.addr > 7)) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   301
		hw_dbg("PHY I2C Address %d is out of range.\n",
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   302
			  hw->phy.addr);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   303
		return -E1000_ERR_CONFIG;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   304
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   305
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   306
	/* Swap the data bytes for the I2C interface */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   307
	phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   308
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   309
	/* Set up Op-code, Phy Address, and register address in the I2CCMD
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   310
	 * register.  The MAC will take care of interfacing with the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   311
	 * PHY to retrieve the desired data.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   312
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   313
	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   314
		  (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   315
		  E1000_I2CCMD_OPCODE_WRITE |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   316
		  phy_data_swapped);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   317
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   318
	wr32(E1000_I2CCMD, i2ccmd);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   319
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   320
	/* Poll the ready bit to see if the I2C read completed */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   321
	for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   322
		udelay(50);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   323
		i2ccmd = rd32(E1000_I2CCMD);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   324
		if (i2ccmd & E1000_I2CCMD_READY)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   325
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   326
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   327
	if (!(i2ccmd & E1000_I2CCMD_READY)) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   328
		hw_dbg("I2CCMD Write did not complete\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   329
		return -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   330
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   331
	if (i2ccmd & E1000_I2CCMD_ERROR) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   332
		hw_dbg("I2CCMD Error bit set\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   333
		return -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   334
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   335
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   336
	return 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   337
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   338
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   339
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   340
 *  igb_read_sfp_data_byte - Reads SFP module data.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   341
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   342
 *  @offset: byte location offset to be read
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   343
 *  @data: read data buffer pointer
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   344
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   345
 *  Reads one byte from SFP module data stored
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   346
 *  in SFP resided EEPROM memory or SFP diagnostic area.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   347
 *  Function should be called with
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   348
 *  E1000_I2CCMD_SFP_DATA_ADDR(<byte offset>) for SFP module database access
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   349
 *  E1000_I2CCMD_SFP_DIAG_ADDR(<byte offset>) for SFP diagnostics parameters
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   350
 *  access
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   351
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   352
s32 igb_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   353
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   354
	u32 i = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   355
	u32 i2ccmd = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   356
	u32 data_local = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   357
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   358
	if (offset > E1000_I2CCMD_SFP_DIAG_ADDR(255)) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   359
		hw_dbg("I2CCMD command address exceeds upper limit\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   360
		return -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   361
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   362
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   363
	/* Set up Op-code, EEPROM Address,in the I2CCMD
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   364
	 * register. The MAC will take care of interfacing with the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   365
	 * EEPROM to retrieve the desired data.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   366
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   367
	i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   368
		  E1000_I2CCMD_OPCODE_READ);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   369
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   370
	wr32(E1000_I2CCMD, i2ccmd);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   371
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   372
	/* Poll the ready bit to see if the I2C read completed */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   373
	for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   374
		udelay(50);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   375
		data_local = rd32(E1000_I2CCMD);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   376
		if (data_local & E1000_I2CCMD_READY)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   377
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   378
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   379
	if (!(data_local & E1000_I2CCMD_READY)) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   380
		hw_dbg("I2CCMD Read did not complete\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   381
		return -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   382
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   383
	if (data_local & E1000_I2CCMD_ERROR) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   384
		hw_dbg("I2CCMD Error bit set\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   385
		return -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   386
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   387
	*data = (u8) data_local & 0xFF;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   388
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   389
	return 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   390
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   391
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   392
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   393
 *  igb_read_phy_reg_igp - Read igp PHY register
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   394
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   395
 *  @offset: register offset to be read
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   396
 *  @data: pointer to the read data
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   397
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   398
 *  Acquires semaphore, if necessary, then reads the PHY register at offset
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   399
 *  and storing the retrieved information in data.  Release any acquired
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   400
 *  semaphores before exiting.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   401
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   402
s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   403
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   404
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   405
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   406
	if (!(hw->phy.ops.acquire))
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   407
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   408
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   409
	ret_val = hw->phy.ops.acquire(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   410
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   411
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   412
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   413
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   414
		ret_val = igb_write_phy_reg_mdic(hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   415
						 IGP01E1000_PHY_PAGE_SELECT,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   416
						 (u16)offset);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   417
		if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   418
			hw->phy.ops.release(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   419
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   420
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   421
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   422
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   423
	ret_val = igb_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   424
					data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   425
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   426
	hw->phy.ops.release(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   427
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   428
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   429
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   430
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   431
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   432
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   433
 *  igb_write_phy_reg_igp - Write igp PHY register
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   434
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   435
 *  @offset: register offset to write to
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   436
 *  @data: data to write at register offset
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   437
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   438
 *  Acquires semaphore, if necessary, then writes the data to PHY register
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   439
 *  at the offset.  Release any acquired semaphores before exiting.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   440
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   441
s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   442
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   443
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   444
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   445
	if (!(hw->phy.ops.acquire))
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   446
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   447
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   448
	ret_val = hw->phy.ops.acquire(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   449
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   450
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   451
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   452
	if (offset > MAX_PHY_MULTI_PAGE_REG) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   453
		ret_val = igb_write_phy_reg_mdic(hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   454
						 IGP01E1000_PHY_PAGE_SELECT,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   455
						 (u16)offset);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   456
		if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   457
			hw->phy.ops.release(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   458
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   459
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   460
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   461
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   462
	ret_val = igb_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   463
					 data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   464
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   465
	hw->phy.ops.release(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   466
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   467
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   468
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   469
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   470
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   471
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   472
 *  igb_copper_link_setup_82580 - Setup 82580 PHY for copper link
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   473
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   474
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   475
 *  Sets up Carrier-sense on Transmit and downshift values.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   476
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   477
s32 igb_copper_link_setup_82580(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   478
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   479
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   480
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   481
	u16 phy_data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   482
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   483
	if (phy->reset_disable) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   484
		ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   485
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   486
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   487
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   488
	if (phy->type == e1000_phy_82580) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   489
		ret_val = hw->phy.ops.reset(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   490
		if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   491
			hw_dbg("Error resetting the PHY.\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   492
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   493
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   494
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   495
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   496
	/* Enable CRS on TX. This must be set for half-duplex operation. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   497
	ret_val = phy->ops.read_reg(hw, I82580_CFG_REG, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   498
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   499
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   500
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   501
	phy_data |= I82580_CFG_ASSERT_CRS_ON_TX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   502
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   503
	/* Enable downshift */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   504
	phy_data |= I82580_CFG_ENABLE_DOWNSHIFT;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   505
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   506
	ret_val = phy->ops.write_reg(hw, I82580_CFG_REG, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   507
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   508
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   509
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   510
	/* Set MDI/MDIX mode */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   511
	ret_val = phy->ops.read_reg(hw, I82580_PHY_CTRL_2, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   512
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   513
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   514
	phy_data &= ~I82580_PHY_CTRL2_MDIX_CFG_MASK;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   515
	/* Options:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   516
	 *   0 - Auto (default)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   517
	 *   1 - MDI mode
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   518
	 *   2 - MDI-X mode
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   519
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   520
	switch (hw->phy.mdix) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   521
	case 1:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   522
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   523
	case 2:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   524
		phy_data |= I82580_PHY_CTRL2_MANUAL_MDIX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   525
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   526
	case 0:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   527
	default:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   528
		phy_data |= I82580_PHY_CTRL2_AUTO_MDI_MDIX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   529
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   530
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   531
	ret_val = hw->phy.ops.write_reg(hw, I82580_PHY_CTRL_2, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   532
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   533
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   534
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   535
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   536
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   537
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   538
 *  igb_copper_link_setup_m88 - Setup m88 PHY's for copper link
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   539
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   540
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   541
 *  Sets up MDI/MDI-X and polarity for m88 PHY's.  If necessary, transmit clock
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   542
 *  and downshift values are set also.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   543
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   544
s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   545
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   546
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   547
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   548
	u16 phy_data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   549
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   550
	if (phy->reset_disable) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   551
		ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   552
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   553
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   554
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   555
	/* Enable CRS on TX. This must be set for half-duplex operation. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   556
	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   557
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   558
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   559
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   560
	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   561
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   562
	/* Options:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   563
	 *   MDI/MDI-X = 0 (default)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   564
	 *   0 - Auto for all speeds
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   565
	 *   1 - MDI mode
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   566
	 *   2 - MDI-X mode
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   567
	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   568
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   569
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   570
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   571
	switch (phy->mdix) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   572
	case 1:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   573
		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   574
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   575
	case 2:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   576
		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   577
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   578
	case 3:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   579
		phy_data |= M88E1000_PSCR_AUTO_X_1000T;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   580
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   581
	case 0:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   582
	default:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   583
		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   584
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   585
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   586
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   587
	/* Options:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   588
	 *   disable_polarity_correction = 0 (default)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   589
	 *       Automatic Correction for Reversed Cable Polarity
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   590
	 *   0 - Disabled
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   591
	 *   1 - Enabled
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   592
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   593
	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   594
	if (phy->disable_polarity_correction == 1)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   595
		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   596
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   597
	ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   598
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   599
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   600
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   601
	if (phy->revision < E1000_REVISION_4) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   602
		/* Force TX_CLK in the Extended PHY Specific Control Register
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   603
		 * to 25MHz clock.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   604
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   605
		ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   606
					    &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   607
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   608
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   609
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   610
		phy_data |= M88E1000_EPSCR_TX_CLK_25;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   611
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   612
		if ((phy->revision == E1000_REVISION_2) &&
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   613
		    (phy->id == M88E1111_I_PHY_ID)) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   614
			/* 82573L PHY - set the downshift counter to 5x. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   615
			phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   616
			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   617
		} else {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   618
			/* Configure Master and Slave downshift values */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   619
			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   620
				      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   621
			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   622
				     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   623
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   624
		ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   625
					     phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   626
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   627
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   628
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   629
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   630
	/* Commit the changes. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   631
	ret_val = igb_phy_sw_reset(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   632
	if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   633
		hw_dbg("Error committing the PHY changes\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   634
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   635
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   636
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   637
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   638
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   639
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   640
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   641
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   642
 *  igb_copper_link_setup_m88_gen2 - Setup m88 PHY's for copper link
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   643
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   644
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   645
 *  Sets up MDI/MDI-X and polarity for i347-AT4, m88e1322 and m88e1112 PHY's.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   646
 *  Also enables and sets the downshift parameters.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   647
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   648
s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   649
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   650
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   651
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   652
	u16 phy_data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   653
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   654
	if (phy->reset_disable)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   655
		return 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   656
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   657
	/* Enable CRS on Tx. This must be set for half-duplex operation. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   658
	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   659
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   660
		return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   661
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   662
	/* Options:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   663
	 *   MDI/MDI-X = 0 (default)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   664
	 *   0 - Auto for all speeds
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   665
	 *   1 - MDI mode
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   666
	 *   2 - MDI-X mode
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   667
	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   668
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   669
	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   670
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   671
	switch (phy->mdix) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   672
	case 1:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   673
		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   674
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   675
	case 2:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   676
		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   677
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   678
	case 3:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   679
		/* M88E1112 does not support this mode) */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   680
		if (phy->id != M88E1112_E_PHY_ID) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   681
			phy_data |= M88E1000_PSCR_AUTO_X_1000T;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   682
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   683
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   684
	case 0:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   685
	default:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   686
		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   687
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   688
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   689
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   690
	/* Options:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   691
	 *   disable_polarity_correction = 0 (default)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   692
	 *       Automatic Correction for Reversed Cable Polarity
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   693
	 *   0 - Disabled
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   694
	 *   1 - Enabled
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   695
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   696
	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   697
	if (phy->disable_polarity_correction == 1)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   698
		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   699
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   700
	/* Enable downshift and setting it to X6 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   701
	if (phy->id == M88E1543_E_PHY_ID) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   702
		phy_data &= ~I347AT4_PSCR_DOWNSHIFT_ENABLE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   703
		ret_val =
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   704
		    phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   705
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   706
			return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   707
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   708
		ret_val = igb_phy_sw_reset(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   709
		if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   710
			hw_dbg("Error committing the PHY changes\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   711
			return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   712
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   713
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   714
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   715
	phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   716
	phy_data |= I347AT4_PSCR_DOWNSHIFT_6X;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   717
	phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   718
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   719
	ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   720
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   721
		return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   722
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   723
	/* Commit the changes. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   724
	ret_val = igb_phy_sw_reset(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   725
	if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   726
		hw_dbg("Error committing the PHY changes\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   727
		return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   728
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   729
	ret_val = igb_set_master_slave_mode(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   730
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   731
		return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   732
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   733
	return 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   734
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   735
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   736
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   737
 *  igb_copper_link_setup_igp - Setup igp PHY's for copper link
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   738
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   739
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   740
 *  Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   741
 *  igp PHY's.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   742
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   743
s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   744
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   745
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   746
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   747
	u16 data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   748
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   749
	if (phy->reset_disable) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   750
		ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   751
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   752
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   753
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   754
	ret_val = phy->ops.reset(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   755
	if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   756
		hw_dbg("Error resetting the PHY.\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   757
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   758
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   759
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   760
	/* Wait 100ms for MAC to configure PHY from NVM settings, to avoid
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   761
	 * timeout issues when LFS is enabled.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   762
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   763
	msleep(100);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   764
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   765
	/* The NVM settings will configure LPLU in D3 for
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   766
	 * non-IGP1 PHYs.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   767
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   768
	if (phy->type == e1000_phy_igp) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   769
		/* disable lplu d3 during driver init */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   770
		if (phy->ops.set_d3_lplu_state)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   771
			ret_val = phy->ops.set_d3_lplu_state(hw, false);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   772
		if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   773
			hw_dbg("Error Disabling LPLU D3\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   774
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   775
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   776
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   777
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   778
	/* disable lplu d0 during driver init */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   779
	ret_val = phy->ops.set_d0_lplu_state(hw, false);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   780
	if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   781
		hw_dbg("Error Disabling LPLU D0\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   782
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   783
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   784
	/* Configure mdi-mdix settings */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   785
	ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   786
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   787
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   788
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   789
	data &= ~IGP01E1000_PSCR_AUTO_MDIX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   790
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   791
	switch (phy->mdix) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   792
	case 1:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   793
		data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   794
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   795
	case 2:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   796
		data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   797
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   798
	case 0:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   799
	default:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   800
		data |= IGP01E1000_PSCR_AUTO_MDIX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   801
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   802
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   803
	ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   804
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   805
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   806
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   807
	/* set auto-master slave resolution settings */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   808
	if (hw->mac.autoneg) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   809
		/* when autonegotiation advertisement is only 1000Mbps then we
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   810
		 * should disable SmartSpeed and enable Auto MasterSlave
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   811
		 * resolution as hardware default.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   812
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   813
		if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   814
			/* Disable SmartSpeed */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   815
			ret_val = phy->ops.read_reg(hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   816
						    IGP01E1000_PHY_PORT_CONFIG,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   817
						    &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   818
			if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   819
				goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   820
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   821
			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   822
			ret_val = phy->ops.write_reg(hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   823
						     IGP01E1000_PHY_PORT_CONFIG,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   824
						     data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   825
			if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   826
				goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   827
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   828
			/* Set auto Master/Slave resolution process */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   829
			ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   830
			if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   831
				goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   832
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   833
			data &= ~CR_1000T_MS_ENABLE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   834
			ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   835
			if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   836
				goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   837
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   838
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   839
		ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   840
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   841
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   842
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   843
		/* load defaults for future use */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   844
		phy->original_ms_type = (data & CR_1000T_MS_ENABLE) ?
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   845
			((data & CR_1000T_MS_VALUE) ?
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   846
			e1000_ms_force_master :
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   847
			e1000_ms_force_slave) :
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   848
			e1000_ms_auto;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   849
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   850
		switch (phy->ms_type) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   851
		case e1000_ms_force_master:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   852
			data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   853
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   854
		case e1000_ms_force_slave:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   855
			data |= CR_1000T_MS_ENABLE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   856
			data &= ~(CR_1000T_MS_VALUE);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   857
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   858
		case e1000_ms_auto:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   859
			data &= ~CR_1000T_MS_ENABLE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   860
		default:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   861
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   862
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   863
		ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   864
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   865
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   866
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   867
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   868
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   869
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   870
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   871
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   872
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   873
 *  igb_copper_link_autoneg - Setup/Enable autoneg for copper link
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   874
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   875
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   876
 *  Performs initial bounds checking on autoneg advertisement parameter, then
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   877
 *  configure to advertise the full capability.  Setup the PHY to autoneg
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   878
 *  and restart the negotiation process between the link partner.  If
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   879
 *  autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   880
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   881
static s32 igb_copper_link_autoneg(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   882
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   883
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   884
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   885
	u16 phy_ctrl;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   886
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   887
	/* Perform some bounds checking on the autoneg advertisement
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   888
	 * parameter.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   889
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   890
	phy->autoneg_advertised &= phy->autoneg_mask;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   891
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   892
	/* If autoneg_advertised is zero, we assume it was not defaulted
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   893
	 * by the calling code so we set to advertise full capability.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   894
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   895
	if (phy->autoneg_advertised == 0)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   896
		phy->autoneg_advertised = phy->autoneg_mask;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   897
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   898
	hw_dbg("Reconfiguring auto-neg advertisement params\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   899
	ret_val = igb_phy_setup_autoneg(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   900
	if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   901
		hw_dbg("Error Setting up Auto-Negotiation\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   902
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   903
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   904
	hw_dbg("Restarting Auto-Neg\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   905
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   906
	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   907
	 * the Auto Neg Restart bit in the PHY control register.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   908
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   909
	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   910
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   911
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   912
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   913
	phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   914
	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   915
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   916
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   917
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   918
	/* Does the user want to wait for Auto-Neg to complete here, or
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   919
	 * check at a later time (for example, callback routine).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   920
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   921
	if (phy->autoneg_wait_to_complete) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   922
		ret_val = igb_wait_autoneg(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   923
		if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   924
			hw_dbg("Error while waiting for autoneg to complete\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   925
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   926
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   927
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   928
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   929
	hw->mac.get_link_status = true;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   930
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   931
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   932
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   933
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   934
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   935
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   936
 *  igb_phy_setup_autoneg - Configure PHY for auto-negotiation
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   937
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   938
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   939
 *  Reads the MII auto-neg advertisement register and/or the 1000T control
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   940
 *  register and if the PHY is already setup for auto-negotiation, then
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   941
 *  return successful.  Otherwise, setup advertisement and flow control to
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   942
 *  the appropriate values for the wanted auto-negotiation.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   943
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   944
static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   945
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   946
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   947
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   948
	u16 mii_autoneg_adv_reg;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   949
	u16 mii_1000t_ctrl_reg = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   950
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   951
	phy->autoneg_advertised &= phy->autoneg_mask;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   952
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   953
	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   954
	ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   955
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   956
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   957
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   958
	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   959
		/* Read the MII 1000Base-T Control Register (Address 9). */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   960
		ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   961
					    &mii_1000t_ctrl_reg);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   962
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   963
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   964
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   965
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   966
	/* Need to parse both autoneg_advertised and fc and set up
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   967
	 * the appropriate PHY registers.  First we will parse for
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   968
	 * autoneg_advertised software override.  Since we can advertise
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   969
	 * a plethora of combinations, we need to check each bit
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   970
	 * individually.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   971
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   972
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   973
	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   974
	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   975
	 * the  1000Base-T Control Register (Address 9).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   976
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   977
	mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   978
				 NWAY_AR_100TX_HD_CAPS |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   979
				 NWAY_AR_10T_FD_CAPS   |
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   980
				 NWAY_AR_10T_HD_CAPS);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   981
	mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   982
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   983
	hw_dbg("autoneg_advertised %x\n", phy->autoneg_advertised);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   984
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   985
	/* Do we want to advertise 10 Mb Half Duplex? */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   986
	if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   987
		hw_dbg("Advertise 10mb Half duplex\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   988
		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   989
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   990
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   991
	/* Do we want to advertise 10 Mb Full Duplex? */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   992
	if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   993
		hw_dbg("Advertise 10mb Full duplex\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   994
		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   995
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   996
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   997
	/* Do we want to advertise 100 Mb Half Duplex? */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   998
	if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
   999
		hw_dbg("Advertise 100mb Half duplex\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1000
		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1001
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1002
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1003
	/* Do we want to advertise 100 Mb Full Duplex? */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1004
	if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1005
		hw_dbg("Advertise 100mb Full duplex\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1006
		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1007
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1008
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1009
	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1010
	if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1011
		hw_dbg("Advertise 1000mb Half duplex request denied!\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1012
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1013
	/* Do we want to advertise 1000 Mb Full Duplex? */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1014
	if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1015
		hw_dbg("Advertise 1000mb Full duplex\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1016
		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1017
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1018
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1019
	/* Check for a software override of the flow control settings, and
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1020
	 * setup the PHY advertisement registers accordingly.  If
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1021
	 * auto-negotiation is enabled, then software will have to set the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1022
	 * "PAUSE" bits to the correct value in the Auto-Negotiation
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1023
	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1024
	 * negotiation.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1025
	 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1026
	 * The possible values of the "fc" parameter are:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1027
	 *      0:  Flow control is completely disabled
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1028
	 *      1:  Rx flow control is enabled (we can receive pause frames
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1029
	 *          but not send pause frames).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1030
	 *      2:  Tx flow control is enabled (we can send pause frames
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1031
	 *          but we do not support receiving pause frames).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1032
	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1033
	 *  other:  No software override.  The flow control configuration
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1034
	 *          in the EEPROM is used.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1035
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1036
	switch (hw->fc.current_mode) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1037
	case e1000_fc_none:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1038
		/* Flow control (RX & TX) is completely disabled by a
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1039
		 * software over-ride.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1040
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1041
		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1042
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1043
	case e1000_fc_rx_pause:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1044
		/* RX Flow control is enabled, and TX Flow control is
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1045
		 * disabled, by a software over-ride.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1046
		 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1047
		 * Since there really isn't a way to advertise that we are
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1048
		 * capable of RX Pause ONLY, we will advertise that we
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1049
		 * support both symmetric and asymmetric RX PAUSE.  Later
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1050
		 * (in e1000_config_fc_after_link_up) we will disable the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1051
		 * hw's ability to send PAUSE frames.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1052
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1053
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1054
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1055
	case e1000_fc_tx_pause:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1056
		/* TX Flow control is enabled, and RX Flow control is
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1057
		 * disabled, by a software over-ride.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1058
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1059
		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1060
		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1061
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1062
	case e1000_fc_full:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1063
		/* Flow control (both RX and TX) is enabled by a software
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1064
		 * over-ride.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1065
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1066
		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1067
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1068
	default:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1069
		hw_dbg("Flow control param set incorrectly\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1070
		ret_val = -E1000_ERR_CONFIG;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1071
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1072
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1073
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1074
	ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1075
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1076
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1077
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1078
	hw_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1079
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1080
	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1081
		ret_val = phy->ops.write_reg(hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1082
					     PHY_1000T_CTRL,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1083
					     mii_1000t_ctrl_reg);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1084
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1085
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1086
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1087
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1088
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1089
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1090
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1091
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1092
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1093
 *  igb_setup_copper_link - Configure copper link settings
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1094
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1095
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1096
 *  Calls the appropriate function to configure the link for auto-neg or forced
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1097
 *  speed and duplex.  Then we check for link, once link is established calls
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1098
 *  to configure collision distance and flow control are called.  If link is
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1099
 *  not established, we return -E1000_ERR_PHY (-2).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1100
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1101
s32 igb_setup_copper_link(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1102
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1103
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1104
	bool link;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1105
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1106
	if (hw->mac.autoneg) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1107
		/* Setup autoneg and flow control advertisement and perform
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1108
		 * autonegotiation.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1109
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1110
		ret_val = igb_copper_link_autoneg(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1111
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1112
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1113
	} else {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1114
		/* PHY will be set to 10H, 10F, 100H or 100F
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1115
		 * depending on user settings.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1116
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1117
		hw_dbg("Forcing Speed and Duplex\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1118
		ret_val = hw->phy.ops.force_speed_duplex(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1119
		if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1120
			hw_dbg("Error Forcing Speed and Duplex\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1121
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1122
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1123
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1124
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1125
	/* Check link status. Wait up to 100 microseconds for link to become
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1126
	 * valid.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1127
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1128
	ret_val = igb_phy_has_link(hw, COPPER_LINK_UP_LIMIT, 10, &link);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1129
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1130
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1131
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1132
	if (link) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1133
		hw_dbg("Valid link established!!!\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1134
		igb_config_collision_dist(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1135
		ret_val = igb_config_fc_after_link_up(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1136
	} else {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1137
		hw_dbg("Unable to establish link!!!\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1138
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1139
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1140
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1141
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1142
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1143
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1144
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1145
 *  igb_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1146
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1147
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1148
 *  Calls the PHY setup function to force speed and duplex.  Clears the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1149
 *  auto-crossover to force MDI manually.  Waits for link and returns
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1150
 *  successful if link up is successful, else -E1000_ERR_PHY (-2).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1151
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1152
s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1153
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1154
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1155
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1156
	u16 phy_data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1157
	bool link;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1158
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1159
	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1160
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1161
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1162
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1163
	igb_phy_force_speed_duplex_setup(hw, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1164
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1165
	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1166
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1167
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1168
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1169
	/* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1170
	 * forced whenever speed and duplex are forced.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1171
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1172
	ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1173
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1174
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1175
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1176
	phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1177
	phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1178
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1179
	ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1180
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1181
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1182
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1183
	hw_dbg("IGP PSCR: %X\n", phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1184
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1185
	udelay(1);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1186
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1187
	if (phy->autoneg_wait_to_complete) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1188
		hw_dbg("Waiting for forced speed/duplex link on IGP phy.\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1189
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1190
		ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 10000, &link);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1191
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1192
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1193
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1194
		if (!link)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1195
			hw_dbg("Link taking longer than expected.\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1196
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1197
		/* Try once more */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1198
		ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 10000, &link);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1199
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1200
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1201
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1202
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1203
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1204
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1205
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1206
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1207
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1208
 *  igb_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1209
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1210
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1211
 *  Calls the PHY setup function to force speed and duplex.  Clears the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1212
 *  auto-crossover to force MDI manually.  Resets the PHY to commit the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1213
 *  changes.  If time expires while waiting for link up, we reset the DSP.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1214
 *  After reset, TX_CLK and CRS on TX must be set.  Return successful upon
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1215
 *  successful completion, else return corresponding error code.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1216
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1217
s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1218
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1219
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1220
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1221
	u16 phy_data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1222
	bool link;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1223
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1224
	/* I210 and I211 devices support Auto-Crossover in forced operation. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1225
	if (phy->type != e1000_phy_i210) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1226
		/* Clear Auto-Crossover to force MDI manually.  M88E1000
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1227
		 * requires MDI forced whenever speed and duplex are forced.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1228
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1229
		ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1230
					    &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1231
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1232
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1233
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1234
		phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1235
		ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1236
					     phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1237
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1238
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1239
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1240
		hw_dbg("M88E1000 PSCR: %X\n", phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1241
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1242
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1243
	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1244
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1245
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1246
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1247
	igb_phy_force_speed_duplex_setup(hw, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1248
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1249
	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1250
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1251
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1252
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1253
	/* Reset the phy to commit changes. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1254
	ret_val = igb_phy_sw_reset(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1255
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1256
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1257
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1258
	if (phy->autoneg_wait_to_complete) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1259
		hw_dbg("Waiting for forced speed/duplex link on M88 phy.\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1260
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1261
		ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 100000, &link);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1262
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1263
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1264
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1265
		if (!link) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1266
			bool reset_dsp = true;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1267
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1268
			switch (hw->phy.id) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1269
			case I347AT4_E_PHY_ID:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1270
			case M88E1112_E_PHY_ID:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1271
			case I210_I_PHY_ID:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1272
				reset_dsp = false;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1273
				break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1274
			default:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1275
				if (hw->phy.type != e1000_phy_m88)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1276
					reset_dsp = false;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1277
				break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1278
			}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1279
			if (!reset_dsp)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1280
				hw_dbg("Link taking longer than expected.\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1281
			else {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1282
				/* We didn't get link.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1283
				 * Reset the DSP and cross our fingers.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1284
				 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1285
				ret_val = phy->ops.write_reg(hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1286
						M88E1000_PHY_PAGE_SELECT,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1287
						0x001d);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1288
				if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1289
					goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1290
				ret_val = igb_phy_reset_dsp(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1291
				if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1292
					goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1293
			}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1294
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1295
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1296
		/* Try once more */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1297
		ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1298
					   100000, &link);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1299
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1300
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1301
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1302
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1303
	if (hw->phy.type != e1000_phy_m88 ||
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1304
	    hw->phy.id == I347AT4_E_PHY_ID ||
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1305
	    hw->phy.id == M88E1112_E_PHY_ID ||
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1306
	    hw->phy.id == I210_I_PHY_ID)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1307
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1308
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1309
	ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1310
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1311
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1312
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1313
	/* Resetting the phy means we need to re-force TX_CLK in the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1314
	 * Extended PHY Specific Control Register to 25MHz clock from
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1315
	 * the reset value of 2.5MHz.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1316
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1317
	phy_data |= M88E1000_EPSCR_TX_CLK_25;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1318
	ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1319
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1320
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1321
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1322
	/* In addition, we must re-enable CRS on Tx for both half and full
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1323
	 * duplex.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1324
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1325
	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1326
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1327
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1328
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1329
	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1330
	ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1331
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1332
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1333
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1334
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1335
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1336
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1337
 *  igb_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1338
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1339
 *  @phy_ctrl: pointer to current value of PHY_CONTROL
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1340
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1341
 *  Forces speed and duplex on the PHY by doing the following: disable flow
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1342
 *  control, force speed/duplex on the MAC, disable auto speed detection,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1343
 *  disable auto-negotiation, configure duplex, configure speed, configure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1344
 *  the collision distance, write configuration to CTRL register.  The
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1345
 *  caller must write to the PHY_CONTROL register for these settings to
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1346
 *  take affect.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1347
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1348
static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1349
					     u16 *phy_ctrl)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1350
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1351
	struct e1000_mac_info *mac = &hw->mac;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1352
	u32 ctrl;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1353
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1354
	/* Turn off flow control when forcing speed/duplex */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1355
	hw->fc.current_mode = e1000_fc_none;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1356
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1357
	/* Force speed/duplex on the mac */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1358
	ctrl = rd32(E1000_CTRL);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1359
	ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1360
	ctrl &= ~E1000_CTRL_SPD_SEL;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1361
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1362
	/* Disable Auto Speed Detection */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1363
	ctrl &= ~E1000_CTRL_ASDE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1364
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1365
	/* Disable autoneg on the phy */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1366
	*phy_ctrl &= ~MII_CR_AUTO_NEG_EN;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1367
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1368
	/* Forcing Full or Half Duplex? */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1369
	if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1370
		ctrl &= ~E1000_CTRL_FD;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1371
		*phy_ctrl &= ~MII_CR_FULL_DUPLEX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1372
		hw_dbg("Half Duplex\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1373
	} else {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1374
		ctrl |= E1000_CTRL_FD;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1375
		*phy_ctrl |= MII_CR_FULL_DUPLEX;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1376
		hw_dbg("Full Duplex\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1377
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1378
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1379
	/* Forcing 10mb or 100mb? */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1380
	if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1381
		ctrl |= E1000_CTRL_SPD_100;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1382
		*phy_ctrl |= MII_CR_SPEED_100;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1383
		*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1384
		hw_dbg("Forcing 100mb\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1385
	} else {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1386
		ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1387
		*phy_ctrl |= MII_CR_SPEED_10;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1388
		*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1389
		hw_dbg("Forcing 10mb\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1390
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1391
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1392
	igb_config_collision_dist(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1393
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1394
	wr32(E1000_CTRL, ctrl);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1395
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1396
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1397
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1398
 *  igb_set_d3_lplu_state - Sets low power link up state for D3
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1399
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1400
 *  @active: boolean used to enable/disable lplu
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1401
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1402
 *  Success returns 0, Failure returns 1
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1403
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1404
 *  The low power link up (lplu) state is set to the power management level D3
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1405
 *  and SmartSpeed is disabled when active is true, else clear lplu for D3
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1406
 *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1407
 *  is used during Dx states where the power conservation is most important.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1408
 *  During driver activity, SmartSpeed should be enabled so performance is
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1409
 *  maintained.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1410
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1411
s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1412
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1413
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1414
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1415
	u16 data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1416
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1417
	if (!(hw->phy.ops.read_reg))
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1418
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1419
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1420
	ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1421
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1422
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1423
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1424
	if (!active) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1425
		data &= ~IGP02E1000_PM_D3_LPLU;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1426
		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1427
					     data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1428
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1429
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1430
		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1431
		 * during Dx states where the power conservation is most
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1432
		 * important.  During driver activity we should enable
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1433
		 * SmartSpeed, so performance is maintained.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1434
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1435
		if (phy->smart_speed == e1000_smart_speed_on) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1436
			ret_val = phy->ops.read_reg(hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1437
						    IGP01E1000_PHY_PORT_CONFIG,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1438
						    &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1439
			if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1440
				goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1441
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1442
			data |= IGP01E1000_PSCFR_SMART_SPEED;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1443
			ret_val = phy->ops.write_reg(hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1444
						     IGP01E1000_PHY_PORT_CONFIG,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1445
						     data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1446
			if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1447
				goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1448
		} else if (phy->smart_speed == e1000_smart_speed_off) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1449
			ret_val = phy->ops.read_reg(hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1450
						     IGP01E1000_PHY_PORT_CONFIG,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1451
						     &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1452
			if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1453
				goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1454
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1455
			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1456
			ret_val = phy->ops.write_reg(hw,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1457
						     IGP01E1000_PHY_PORT_CONFIG,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1458
						     data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1459
			if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1460
				goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1461
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1462
	} else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1463
		   (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1464
		   (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1465
		data |= IGP02E1000_PM_D3_LPLU;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1466
		ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1467
					      data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1468
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1469
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1470
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1471
		/* When LPLU is enabled, we should disable SmartSpeed */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1472
		ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1473
					    &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1474
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1475
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1476
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1477
		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1478
		ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1479
					     data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1480
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1481
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1482
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1483
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1484
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1485
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1486
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1487
 *  igb_check_downshift - Checks whether a downshift in speed occurred
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1488
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1489
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1490
 *  Success returns 0, Failure returns 1
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1491
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1492
 *  A downshift is detected by querying the PHY link health.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1493
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1494
s32 igb_check_downshift(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1495
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1496
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1497
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1498
	u16 phy_data, offset, mask;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1499
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1500
	switch (phy->type) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1501
	case e1000_phy_i210:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1502
	case e1000_phy_m88:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1503
	case e1000_phy_gg82563:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1504
		offset	= M88E1000_PHY_SPEC_STATUS;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1505
		mask	= M88E1000_PSSR_DOWNSHIFT;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1506
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1507
	case e1000_phy_igp_2:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1508
	case e1000_phy_igp:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1509
	case e1000_phy_igp_3:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1510
		offset	= IGP01E1000_PHY_LINK_HEALTH;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1511
		mask	= IGP01E1000_PLHR_SS_DOWNGRADE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1512
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1513
	default:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1514
		/* speed downshift not supported */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1515
		phy->speed_downgraded = false;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1516
		ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1517
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1518
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1519
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1520
	ret_val = phy->ops.read_reg(hw, offset, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1521
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1522
	if (!ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1523
		phy->speed_downgraded = (phy_data & mask) ? true : false;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1524
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1525
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1526
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1527
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1528
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1529
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1530
 *  igb_check_polarity_m88 - Checks the polarity.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1531
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1532
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1533
 *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1534
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1535
 *  Polarity is determined based on the PHY specific status register.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1536
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1537
s32 igb_check_polarity_m88(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1538
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1539
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1540
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1541
	u16 data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1542
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1543
	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1544
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1545
	if (!ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1546
		phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1547
				      ? e1000_rev_polarity_reversed
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1548
				      : e1000_rev_polarity_normal;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1549
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1550
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1551
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1552
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1553
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1554
 *  igb_check_polarity_igp - Checks the polarity.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1555
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1556
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1557
 *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1558
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1559
 *  Polarity is determined based on the PHY port status register, and the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1560
 *  current speed (since there is no polarity at 100Mbps).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1561
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1562
static s32 igb_check_polarity_igp(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1563
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1564
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1565
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1566
	u16 data, offset, mask;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1567
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1568
	/* Polarity is determined based on the speed of
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1569
	 * our connection.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1570
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1571
	ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1572
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1573
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1574
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1575
	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1576
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1577
		offset	= IGP01E1000_PHY_PCS_INIT_REG;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1578
		mask	= IGP01E1000_PHY_POLARITY_MASK;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1579
	} else {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1580
		/* This really only applies to 10Mbps since
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1581
		 * there is no polarity for 100Mbps (always 0).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1582
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1583
		offset	= IGP01E1000_PHY_PORT_STATUS;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1584
		mask	= IGP01E1000_PSSR_POLARITY_REVERSED;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1585
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1586
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1587
	ret_val = phy->ops.read_reg(hw, offset, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1588
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1589
	if (!ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1590
		phy->cable_polarity = (data & mask)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1591
				      ? e1000_rev_polarity_reversed
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1592
				      : e1000_rev_polarity_normal;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1593
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1594
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1595
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1596
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1597
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1598
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1599
 *  igb_wait_autoneg - Wait for auto-neg completion
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1600
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1601
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1602
 *  Waits for auto-negotiation to complete or for the auto-negotiation time
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1603
 *  limit to expire, which ever happens first.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1604
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1605
static s32 igb_wait_autoneg(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1606
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1607
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1608
	u16 i, phy_status;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1609
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1610
	/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1611
	for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1612
		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1613
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1614
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1615
		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1616
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1617
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1618
		if (phy_status & MII_SR_AUTONEG_COMPLETE)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1619
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1620
		msleep(100);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1621
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1622
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1623
	/* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1624
	 * has completed.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1625
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1626
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1627
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1628
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1629
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1630
 *  igb_phy_has_link - Polls PHY for link
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1631
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1632
 *  @iterations: number of times to poll for link
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1633
 *  @usec_interval: delay between polling attempts
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1634
 *  @success: pointer to whether polling was successful or not
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1635
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1636
 *  Polls the PHY status register for link, 'iterations' number of times.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1637
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1638
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1639
		     u32 usec_interval, bool *success)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1640
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1641
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1642
	u16 i, phy_status;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1643
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1644
	for (i = 0; i < iterations; i++) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1645
		/* Some PHYs require the PHY_STATUS register to be read
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1646
		 * twice due to the link bit being sticky.  No harm doing
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1647
		 * it across the board.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1648
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1649
		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1650
		if (ret_val && usec_interval > 0) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1651
			/* If the first read fails, another entity may have
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1652
			 * ownership of the resources, wait and try again to
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1653
			 * see if they have relinquished the resources yet.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1654
			 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1655
			if (usec_interval >= 1000)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1656
				mdelay(usec_interval/1000);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1657
			else
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1658
				udelay(usec_interval);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1659
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1660
		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1661
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1662
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1663
		if (phy_status & MII_SR_LINK_STATUS)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1664
			break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1665
		if (usec_interval >= 1000)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1666
			mdelay(usec_interval/1000);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1667
		else
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1668
			udelay(usec_interval);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1669
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1670
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1671
	*success = (i < iterations) ? true : false;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1672
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1673
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1674
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1675
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1676
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1677
 *  igb_get_cable_length_m88 - Determine cable length for m88 PHY
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1678
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1679
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1680
 *  Reads the PHY specific status register to retrieve the cable length
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1681
 *  information.  The cable length is determined by averaging the minimum and
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1682
 *  maximum values to get the "average" cable length.  The m88 PHY has four
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1683
 *  possible cable length values, which are:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1684
 *	Register Value		Cable Length
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1685
 *	0			< 50 meters
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1686
 *	1			50 - 80 meters
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1687
 *	2			80 - 110 meters
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1688
 *	3			110 - 140 meters
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1689
 *	4			> 140 meters
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1690
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1691
s32 igb_get_cable_length_m88(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1692
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1693
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1694
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1695
	u16 phy_data, index;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1696
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1697
	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1698
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1699
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1700
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1701
	index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1702
		M88E1000_PSSR_CABLE_LENGTH_SHIFT;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1703
	if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1704
		ret_val = -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1705
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1706
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1707
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1708
	phy->min_cable_length = e1000_m88_cable_length_table[index];
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1709
	phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1710
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1711
	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1712
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1713
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1714
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1715
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1716
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1717
s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1718
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1719
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1720
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1721
	u16 phy_data, phy_data2, index, default_page, is_cm;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1722
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1723
	switch (hw->phy.id) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1724
	case I210_I_PHY_ID:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1725
		/* Get cable length from PHY Cable Diagnostics Control Reg */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1726
		ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) +
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1727
					    (I347AT4_PCDL + phy->addr),
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1728
					    &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1729
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1730
			return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1731
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1732
		/* Check if the unit of cable length is meters or cm */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1733
		ret_val = phy->ops.read_reg(hw, (0x7 << GS40G_PAGE_SHIFT) +
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1734
					    I347AT4_PCDC, &phy_data2);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1735
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1736
			return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1737
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1738
		is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1739
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1740
		/* Populate the phy structure with cable length in meters */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1741
		phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1742
		phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1743
		phy->cable_length = phy_data / (is_cm ? 100 : 1);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1744
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1745
	case M88E1543_E_PHY_ID:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1746
	case I347AT4_E_PHY_ID:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1747
		/* Remember the original page select and set it to 7 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1748
		ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1749
					    &default_page);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1750
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1751
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1752
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1753
		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1754
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1755
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1756
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1757
		/* Get cable length from PHY Cable Diagnostics Control Reg */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1758
		ret_val = phy->ops.read_reg(hw, (I347AT4_PCDL + phy->addr),
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1759
					    &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1760
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1761
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1762
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1763
		/* Check if the unit of cable length is meters or cm */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1764
		ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1765
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1766
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1767
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1768
		is_cm = !(phy_data2 & I347AT4_PCDC_CABLE_LENGTH_UNIT);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1769
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1770
		/* Populate the phy structure with cable length in meters */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1771
		phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1772
		phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1773
		phy->cable_length = phy_data / (is_cm ? 100 : 1);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1774
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1775
		/* Reset the page selec to its original value */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1776
		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1777
					     default_page);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1778
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1779
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1780
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1781
	case M88E1112_E_PHY_ID:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1782
		/* Remember the original page select and set it to 5 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1783
		ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1784
					    &default_page);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1785
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1786
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1787
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1788
		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x05);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1789
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1790
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1791
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1792
		ret_val = phy->ops.read_reg(hw, M88E1112_VCT_DSP_DISTANCE,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1793
					    &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1794
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1795
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1796
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1797
		index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1798
			M88E1000_PSSR_CABLE_LENGTH_SHIFT;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1799
		if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1800
			ret_val = -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1801
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1802
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1803
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1804
		phy->min_cable_length = e1000_m88_cable_length_table[index];
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1805
		phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1806
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1807
		phy->cable_length = (phy->min_cable_length +
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1808
				     phy->max_cable_length) / 2;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1809
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1810
		/* Reset the page select to its original value */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1811
		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1812
					     default_page);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1813
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1814
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1815
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1816
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1817
	default:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1818
		ret_val = -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1819
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1820
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1821
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1822
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1823
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1824
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1825
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1826
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1827
 *  igb_get_cable_length_igp_2 - Determine cable length for igp2 PHY
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1828
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1829
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1830
 *  The automatic gain control (agc) normalizes the amplitude of the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1831
 *  received signal, adjusting for the attenuation produced by the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1832
 *  cable.  By reading the AGC registers, which represent the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1833
 *  combination of coarse and fine gain value, the value can be put
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1834
 *  into a lookup table to obtain the approximate cable length
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1835
 *  for each channel.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1836
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1837
s32 igb_get_cable_length_igp_2(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1838
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1839
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1840
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1841
	u16 phy_data, i, agc_value = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1842
	u16 cur_agc_index, max_agc_index = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1843
	u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1844
	static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1845
		IGP02E1000_PHY_AGC_A,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1846
		IGP02E1000_PHY_AGC_B,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1847
		IGP02E1000_PHY_AGC_C,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1848
		IGP02E1000_PHY_AGC_D
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1849
	};
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1850
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1851
	/* Read the AGC registers for all channels */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1852
	for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1853
		ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1854
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1855
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1856
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1857
		/* Getting bits 15:9, which represent the combination of
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1858
		 * coarse and fine gain values.  The result is a number
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1859
		 * that can be put into the lookup table to obtain the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1860
		 * approximate cable length.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1861
		 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1862
		cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1863
				IGP02E1000_AGC_LENGTH_MASK;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1864
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1865
		/* Array index bound check. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1866
		if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1867
		    (cur_agc_index == 0)) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1868
			ret_val = -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1869
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1870
		}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1871
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1872
		/* Remove min & max AGC values from calculation. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1873
		if (e1000_igp_2_cable_length_table[min_agc_index] >
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1874
		    e1000_igp_2_cable_length_table[cur_agc_index])
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1875
			min_agc_index = cur_agc_index;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1876
		if (e1000_igp_2_cable_length_table[max_agc_index] <
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1877
		    e1000_igp_2_cable_length_table[cur_agc_index])
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1878
			max_agc_index = cur_agc_index;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1879
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1880
		agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1881
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1882
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1883
	agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1884
		      e1000_igp_2_cable_length_table[max_agc_index]);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1885
	agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1886
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1887
	/* Calculate cable length with the error range of +/- 10 meters. */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1888
	phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1889
				 (agc_value - IGP02E1000_AGC_RANGE) : 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1890
	phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1891
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1892
	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1893
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1894
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1895
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1896
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1897
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1898
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1899
 *  igb_get_phy_info_m88 - Retrieve PHY information
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1900
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1901
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1902
 *  Valid for only copper links.  Read the PHY status register (sticky read)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1903
 *  to verify that link is up.  Read the PHY special control register to
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1904
 *  determine the polarity and 10base-T extended distance.  Read the PHY
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1905
 *  special status register to determine MDI/MDIx and current speed.  If
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1906
 *  speed is 1000, then determine cable length, local and remote receiver.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1907
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1908
s32 igb_get_phy_info_m88(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1909
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1910
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1911
	s32  ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1912
	u16 phy_data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1913
	bool link;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1914
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1915
	if (phy->media_type != e1000_media_type_copper) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1916
		hw_dbg("Phy info is only valid for copper media\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1917
		ret_val = -E1000_ERR_CONFIG;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1918
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1919
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1920
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1921
	ret_val = igb_phy_has_link(hw, 1, 0, &link);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1922
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1923
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1924
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1925
	if (!link) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1926
		hw_dbg("Phy info is only valid if link is up\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1927
		ret_val = -E1000_ERR_CONFIG;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1928
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1929
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1930
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1931
	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1932
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1933
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1934
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1935
	phy->polarity_correction = (phy_data & M88E1000_PSCR_POLARITY_REVERSAL)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1936
				   ? true : false;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1937
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1938
	ret_val = igb_check_polarity_m88(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1939
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1940
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1941
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1942
	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1943
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1944
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1945
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1946
	phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? true : false;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1947
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1948
	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1949
		ret_val = phy->ops.get_cable_length(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1950
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1951
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1952
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1953
		ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1954
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1955
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1956
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1957
		phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1958
				? e1000_1000t_rx_status_ok
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1959
				: e1000_1000t_rx_status_not_ok;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1960
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1961
		phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1962
				 ? e1000_1000t_rx_status_ok
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1963
				 : e1000_1000t_rx_status_not_ok;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1964
	} else {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1965
		/* Set values to "undefined" */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1966
		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1967
		phy->local_rx = e1000_1000t_rx_status_undefined;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1968
		phy->remote_rx = e1000_1000t_rx_status_undefined;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1969
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1970
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1971
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1972
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1973
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1974
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1975
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1976
 *  igb_get_phy_info_igp - Retrieve igp PHY information
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1977
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1978
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1979
 *  Read PHY status to determine if link is up.  If link is up, then
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1980
 *  set/determine 10base-T extended distance and polarity correction.  Read
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1981
 *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1982
 *  determine on the cable length, local and remote receiver.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1983
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1984
s32 igb_get_phy_info_igp(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1985
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1986
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1987
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1988
	u16 data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1989
	bool link;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1990
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1991
	ret_val = igb_phy_has_link(hw, 1, 0, &link);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1992
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1993
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1994
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1995
	if (!link) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1996
		hw_dbg("Phy info is only valid if link is up\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1997
		ret_val = -E1000_ERR_CONFIG;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1998
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  1999
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2000
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2001
	phy->polarity_correction = true;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2002
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2003
	ret_val = igb_check_polarity_igp(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2004
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2005
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2006
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2007
	ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2008
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2009
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2010
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2011
	phy->is_mdix = (data & IGP01E1000_PSSR_MDIX) ? true : false;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2012
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2013
	if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2014
	    IGP01E1000_PSSR_SPEED_1000MBPS) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2015
		ret_val = phy->ops.get_cable_length(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2016
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2017
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2018
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2019
		ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2020
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2021
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2022
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2023
		phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2024
				? e1000_1000t_rx_status_ok
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2025
				: e1000_1000t_rx_status_not_ok;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2026
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2027
		phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2028
				 ? e1000_1000t_rx_status_ok
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2029
				 : e1000_1000t_rx_status_not_ok;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2030
	} else {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2031
		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2032
		phy->local_rx = e1000_1000t_rx_status_undefined;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2033
		phy->remote_rx = e1000_1000t_rx_status_undefined;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2034
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2035
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2036
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2037
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2038
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2039
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2040
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2041
 *  igb_phy_sw_reset - PHY software reset
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2042
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2043
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2044
 *  Does a software reset of the PHY by reading the PHY control register and
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2045
 *  setting/write the control register reset bit to the PHY.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2046
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2047
s32 igb_phy_sw_reset(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2048
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2049
	s32 ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2050
	u16 phy_ctrl;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2051
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2052
	if (!(hw->phy.ops.read_reg))
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2053
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2054
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2055
	ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2056
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2057
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2058
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2059
	phy_ctrl |= MII_CR_RESET;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2060
	ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2061
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2062
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2063
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2064
	udelay(1);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2065
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2066
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2067
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2068
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2069
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2070
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2071
 *  igb_phy_hw_reset - PHY hardware reset
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2072
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2073
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2074
 *  Verify the reset block is not blocking us from resetting.  Acquire
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2075
 *  semaphore (if necessary) and read/set/write the device control reset
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2076
 *  bit in the PHY.  Wait the appropriate delay time for the device to
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2077
 *  reset and release the semaphore (if necessary).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2078
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2079
s32 igb_phy_hw_reset(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2080
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2081
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2082
	s32  ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2083
	u32 ctrl;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2084
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2085
	ret_val = igb_check_reset_block(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2086
	if (ret_val) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2087
		ret_val = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2088
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2089
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2090
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2091
	ret_val = phy->ops.acquire(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2092
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2093
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2094
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2095
	ctrl = rd32(E1000_CTRL);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2096
	wr32(E1000_CTRL, ctrl | E1000_CTRL_PHY_RST);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2097
	wrfl();
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2098
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2099
	udelay(phy->reset_delay_us);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2100
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2101
	wr32(E1000_CTRL, ctrl);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2102
	wrfl();
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2103
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2104
	udelay(150);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2105
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2106
	phy->ops.release(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2107
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2108
	ret_val = phy->ops.get_cfg_done(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2109
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2110
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2111
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2112
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2113
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2114
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2115
 *  igb_phy_init_script_igp3 - Inits the IGP3 PHY
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2116
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2117
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2118
 *  Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2119
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2120
s32 igb_phy_init_script_igp3(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2121
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2122
	hw_dbg("Running IGP 3 PHY init script\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2123
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2124
	/* PHY init IGP 3 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2125
	/* Enable rise/fall, 10-mode work in class-A */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2126
	hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2127
	/* Remove all caps from Replica path filter */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2128
	hw->phy.ops.write_reg(hw, 0x2F52, 0x0000);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2129
	/* Bias trimming for ADC, AFE and Driver (Default) */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2130
	hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2131
	/* Increase Hybrid poly bias */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2132
	hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2133
	/* Add 4% to TX amplitude in Giga mode */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2134
	hw->phy.ops.write_reg(hw, 0x2010, 0x10B0);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2135
	/* Disable trimming (TTT) */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2136
	hw->phy.ops.write_reg(hw, 0x2011, 0x0000);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2137
	/* Poly DC correction to 94.6% + 2% for all channels */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2138
	hw->phy.ops.write_reg(hw, 0x20DD, 0x249A);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2139
	/* ABS DC correction to 95.9% */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2140
	hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2141
	/* BG temp curve trim */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2142
	hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2143
	/* Increasing ADC OPAMP stage 1 currents to max */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2144
	hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2145
	/* Force 1000 ( required for enabling PHY regs configuration) */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2146
	hw->phy.ops.write_reg(hw, 0x0000, 0x0140);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2147
	/* Set upd_freq to 6 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2148
	hw->phy.ops.write_reg(hw, 0x1F30, 0x1606);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2149
	/* Disable NPDFE */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2150
	hw->phy.ops.write_reg(hw, 0x1F31, 0xB814);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2151
	/* Disable adaptive fixed FFE (Default) */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2152
	hw->phy.ops.write_reg(hw, 0x1F35, 0x002A);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2153
	/* Enable FFE hysteresis */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2154
	hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2155
	/* Fixed FFE for short cable lengths */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2156
	hw->phy.ops.write_reg(hw, 0x1F54, 0x0065);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2157
	/* Fixed FFE for medium cable lengths */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2158
	hw->phy.ops.write_reg(hw, 0x1F55, 0x002A);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2159
	/* Fixed FFE for long cable lengths */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2160
	hw->phy.ops.write_reg(hw, 0x1F56, 0x002A);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2161
	/* Enable Adaptive Clip Threshold */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2162
	hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2163
	/* AHT reset limit to 1 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2164
	hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2165
	/* Set AHT master delay to 127 msec */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2166
	hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2167
	/* Set scan bits for AHT */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2168
	hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2169
	/* Set AHT Preset bits */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2170
	hw->phy.ops.write_reg(hw, 0x1F79, 0x0210);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2171
	/* Change integ_factor of channel A to 3 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2172
	hw->phy.ops.write_reg(hw, 0x1895, 0x0003);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2173
	/* Change prop_factor of channels BCD to 8 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2174
	hw->phy.ops.write_reg(hw, 0x1796, 0x0008);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2175
	/* Change cg_icount + enable integbp for channels BCD */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2176
	hw->phy.ops.write_reg(hw, 0x1798, 0xD008);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2177
	/* Change cg_icount + enable integbp + change prop_factor_master
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2178
	 * to 8 for channel A
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2179
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2180
	hw->phy.ops.write_reg(hw, 0x1898, 0xD918);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2181
	/* Disable AHT in Slave mode on channel A */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2182
	hw->phy.ops.write_reg(hw, 0x187A, 0x0800);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2183
	/* Enable LPLU and disable AN to 1000 in non-D0a states,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2184
	 * Enable SPD+B2B
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2185
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2186
	hw->phy.ops.write_reg(hw, 0x0019, 0x008D);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2187
	/* Enable restart AN on an1000_dis change */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2188
	hw->phy.ops.write_reg(hw, 0x001B, 0x2080);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2189
	/* Enable wh_fifo read clock in 10/100 modes */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2190
	hw->phy.ops.write_reg(hw, 0x0014, 0x0045);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2191
	/* Restart AN, Speed selection is 1000 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2192
	hw->phy.ops.write_reg(hw, 0x0000, 0x1340);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2193
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2194
	return 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2195
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2196
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2197
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2198
 * igb_power_up_phy_copper - Restore copper link in case of PHY power down
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2199
 * @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2200
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2201
 * In the case of a PHY power down to save power, or to turn off link during a
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2202
 * driver unload, restore the link to previous settings.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2203
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2204
void igb_power_up_phy_copper(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2205
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2206
	u16 mii_reg = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2207
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2208
	/* The PHY will retain its settings across a power down/up cycle */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2209
	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2210
	mii_reg &= ~MII_CR_POWER_DOWN;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2211
	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2212
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2213
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2214
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2215
 * igb_power_down_phy_copper - Power down copper PHY
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2216
 * @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2217
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2218
 * Power down PHY to save power when interface is down and wake on lan
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2219
 * is not enabled.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2220
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2221
void igb_power_down_phy_copper(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2222
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2223
	u16 mii_reg = 0;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2224
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2225
	/* The PHY will retain its settings across a power down/up cycle */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2226
	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2227
	mii_reg |= MII_CR_POWER_DOWN;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2228
	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2229
	usleep_range(1000, 2000);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2230
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2231
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2232
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2233
 *  igb_check_polarity_82580 - Checks the polarity.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2234
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2235
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2236
 *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2237
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2238
 *  Polarity is determined based on the PHY specific status register.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2239
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2240
static s32 igb_check_polarity_82580(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2241
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2242
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2243
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2244
	u16 data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2245
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2246
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2247
	ret_val = phy->ops.read_reg(hw, I82580_PHY_STATUS_2, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2248
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2249
	if (!ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2250
		phy->cable_polarity = (data & I82580_PHY_STATUS2_REV_POLARITY)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2251
				      ? e1000_rev_polarity_reversed
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2252
				      : e1000_rev_polarity_normal;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2253
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2254
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2255
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2256
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2257
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2258
 *  igb_phy_force_speed_duplex_82580 - Force speed/duplex for I82580 PHY
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2259
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2260
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2261
 *  Calls the PHY setup function to force speed and duplex.  Clears the
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2262
 *  auto-crossover to force MDI manually.  Waits for link and returns
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2263
 *  successful if link up is successful, else -E1000_ERR_PHY (-2).
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2264
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2265
s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2266
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2267
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2268
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2269
	u16 phy_data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2270
	bool link;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2271
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2272
	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2273
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2274
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2275
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2276
	igb_phy_force_speed_duplex_setup(hw, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2277
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2278
	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2279
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2280
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2281
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2282
	/* Clear Auto-Crossover to force MDI manually.  82580 requires MDI
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2283
	 * forced whenever speed and duplex are forced.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2284
	 */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2285
	ret_val = phy->ops.read_reg(hw, I82580_PHY_CTRL_2, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2286
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2287
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2288
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2289
	phy_data &= ~I82580_PHY_CTRL2_MDIX_CFG_MASK;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2290
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2291
	ret_val = phy->ops.write_reg(hw, I82580_PHY_CTRL_2, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2292
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2293
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2294
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2295
	hw_dbg("I82580_PHY_CTRL_2: %X\n", phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2296
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2297
	udelay(1);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2298
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2299
	if (phy->autoneg_wait_to_complete) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2300
		hw_dbg("Waiting for forced speed/duplex link on 82580 phy\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2301
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2302
		ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 100000, &link);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2303
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2304
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2305
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2306
		if (!link)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2307
			hw_dbg("Link taking longer than expected.\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2308
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2309
		/* Try once more */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2310
		ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT, 100000, &link);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2311
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2312
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2313
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2314
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2315
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2316
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2317
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2318
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2319
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2320
 *  igb_get_phy_info_82580 - Retrieve I82580 PHY information
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2321
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2322
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2323
 *  Read PHY status to determine if link is up.  If link is up, then
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2324
 *  set/determine 10base-T extended distance and polarity correction.  Read
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2325
 *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2326
 *  determine on the cable length, local and remote receiver.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2327
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2328
s32 igb_get_phy_info_82580(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2329
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2330
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2331
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2332
	u16 data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2333
	bool link;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2334
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2335
	ret_val = igb_phy_has_link(hw, 1, 0, &link);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2336
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2337
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2338
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2339
	if (!link) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2340
		hw_dbg("Phy info is only valid if link is up\n");
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2341
		ret_val = -E1000_ERR_CONFIG;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2342
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2343
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2344
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2345
	phy->polarity_correction = true;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2346
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2347
	ret_val = igb_check_polarity_82580(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2348
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2349
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2350
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2351
	ret_val = phy->ops.read_reg(hw, I82580_PHY_STATUS_2, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2352
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2353
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2354
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2355
	phy->is_mdix = (data & I82580_PHY_STATUS2_MDIX) ? true : false;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2356
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2357
	if ((data & I82580_PHY_STATUS2_SPEED_MASK) ==
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2358
	    I82580_PHY_STATUS2_SPEED_1000MBPS) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2359
		ret_val = hw->phy.ops.get_cable_length(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2360
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2361
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2362
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2363
		ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2364
		if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2365
			goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2366
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2367
		phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2368
				? e1000_1000t_rx_status_ok
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2369
				: e1000_1000t_rx_status_not_ok;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2370
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2371
		phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2372
				 ? e1000_1000t_rx_status_ok
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2373
				 : e1000_1000t_rx_status_not_ok;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2374
	} else {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2375
		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2376
		phy->local_rx = e1000_1000t_rx_status_undefined;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2377
		phy->remote_rx = e1000_1000t_rx_status_undefined;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2378
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2379
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2380
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2381
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2382
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2383
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2384
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2385
 *  igb_get_cable_length_82580 - Determine cable length for 82580 PHY
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2386
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2387
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2388
 * Reads the diagnostic status register and verifies result is valid before
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2389
 * placing it in the phy_cable_length field.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2390
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2391
s32 igb_get_cable_length_82580(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2392
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2393
	struct e1000_phy_info *phy = &hw->phy;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2394
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2395
	u16 phy_data, length;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2396
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2397
	ret_val = phy->ops.read_reg(hw, I82580_PHY_DIAG_STATUS, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2398
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2399
		goto out;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2400
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2401
	length = (phy_data & I82580_DSTATUS_CABLE_LENGTH) >>
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2402
		 I82580_DSTATUS_CABLE_LENGTH_SHIFT;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2403
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2404
	if (length == E1000_CABLE_LENGTH_UNDEFINED)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2405
		ret_val = -E1000_ERR_PHY;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2406
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2407
	phy->cable_length = length;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2408
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2409
out:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2410
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2411
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2412
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2413
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2414
 *  igb_write_phy_reg_gs40g - Write GS40G PHY register
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2415
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2416
 *  @offset: lower half is register offset to write to
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2417
 *     upper half is page to use.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2418
 *  @data: data to write at register offset
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2419
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2420
 *  Acquires semaphore, if necessary, then writes the data to PHY register
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2421
 *  at the offset.  Release any acquired semaphores before exiting.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2422
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2423
s32 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2424
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2425
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2426
	u16 page = offset >> GS40G_PAGE_SHIFT;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2427
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2428
	offset = offset & GS40G_OFFSET_MASK;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2429
	ret_val = hw->phy.ops.acquire(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2430
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2431
		return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2432
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2433
	ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2434
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2435
		goto release;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2436
	ret_val = igb_write_phy_reg_mdic(hw, offset, data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2437
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2438
release:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2439
	hw->phy.ops.release(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2440
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2441
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2442
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2443
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2444
 *  igb_read_phy_reg_gs40g - Read GS40G  PHY register
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2445
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2446
 *  @offset: lower half is register offset to read to
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2447
 *     upper half is page to use.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2448
 *  @data: data to read at register offset
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2449
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2450
 *  Acquires semaphore, if necessary, then reads the data in the PHY register
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2451
 *  at the offset.  Release any acquired semaphores before exiting.
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2452
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2453
s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2454
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2455
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2456
	u16 page = offset >> GS40G_PAGE_SHIFT;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2457
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2458
	offset = offset & GS40G_OFFSET_MASK;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2459
	ret_val = hw->phy.ops.acquire(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2460
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2461
		return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2462
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2463
	ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2464
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2465
		goto release;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2466
	ret_val = igb_read_phy_reg_mdic(hw, offset, data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2467
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2468
release:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2469
	hw->phy.ops.release(hw);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2470
	return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2471
}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2472
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2473
/**
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2474
 *  igb_set_master_slave_mode - Setup PHY for Master/slave mode
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2475
 *  @hw: pointer to the HW structure
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2476
 *
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2477
 *  Sets up Master/slave mode
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2478
 **/
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2479
static s32 igb_set_master_slave_mode(struct e1000_hw *hw)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2480
{
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2481
	s32 ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2482
	u16 phy_data;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2483
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2484
	/* Resolve Master/Slave mode */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2485
	ret_val = hw->phy.ops.read_reg(hw, PHY_1000T_CTRL, &phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2486
	if (ret_val)
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2487
		return ret_val;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2488
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2489
	/* load defaults for future use */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2490
	hw->phy.original_ms_type = (phy_data & CR_1000T_MS_ENABLE) ?
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2491
				   ((phy_data & CR_1000T_MS_VALUE) ?
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2492
				    e1000_ms_force_master :
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2493
				    e1000_ms_force_slave) : e1000_ms_auto;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2494
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2495
	switch (hw->phy.ms_type) {
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2496
	case e1000_ms_force_master:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2497
		phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2498
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2499
	case e1000_ms_force_slave:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2500
		phy_data |= CR_1000T_MS_ENABLE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2501
		phy_data &= ~(CR_1000T_MS_VALUE);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2502
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2503
	case e1000_ms_auto:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2504
		phy_data &= ~CR_1000T_MS_ENABLE;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2505
		/* fall-through */
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2506
	default:
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2507
		break;
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2508
	}
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2509
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2510
	return hw->phy.ops.write_reg(hw, PHY_1000T_CTRL, phy_data);
740291442c05 Added clean igb driver from kernel 3.18 (no EtherCAT yet).
Florian Pose <fp@igh.de>
parents:
diff changeset
  2511
}