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

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2585
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2013 Intel Corporation.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000.h"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
 *  e1000e_get_bus_info_pcie - Get PCIe bus information
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
 *  Determines and stores the system bus information for a particular
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
 *  network interface.  The following bus information is determined and stored:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
 *  bus speed, bus width, type (PCIe), and PCIe function.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
	struct e1000_mac_info *mac = &hw->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
	struct e1000_bus_info *bus = &hw->bus;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
	struct e1000_adapter *adapter = hw->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
	u16 pcie_link_status, cap_offset;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	cap_offset = adapter->pdev->pcie_cap;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
	if (!cap_offset) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
		bus->width = e1000_bus_width_unknown;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
		pci_read_config_word(adapter->pdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
				     cap_offset + PCIE_LINK_STATUS,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
				     &pcie_link_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
		bus->width = (enum e1000_bus_width)((pcie_link_status &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
						     PCIE_LINK_WIDTH_MASK) >>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
						    PCIE_LINK_WIDTH_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	mac->ops.set_lan_id(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
 *  e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
 *  Determines the LAN function id by reading memory-mapped registers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
 *  and swaps the port value if requested.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	struct e1000_bus_info *bus = &hw->bus;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	u32 reg;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	/* The status register reports the correct function number
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	 * for the device regardless of function swap state.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	reg = er32(STATUS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
 *  e1000_set_lan_id_single_port - Set LAN id for a single port device
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
 *  Sets the LAN function id to zero for a single port device.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
void e1000_set_lan_id_single_port(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	struct e1000_bus_info *bus = &hw->bus;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	bus->func = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
 *  e1000_clear_vfta_generic - Clear VLAN filter table
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
 *  Clears the register array which contains the VLAN filter table by
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
 *  setting all the values to 0.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
void e1000_clear_vfta_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	u32 offset;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
		e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
 *  e1000_write_vfta_generic - Write value to VLAN filter table
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
 *  @offset: register offset in VLAN filter table
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
 *  @value: register value written to VLAN filter table
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
 *  Writes value at the given offset in the register array which stores
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
 *  the VLAN filter table.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
 *  e1000e_init_rx_addrs - Initialize receive address's
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
 *  @rar_count: receive address registers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
 *  Setup the receive address registers by setting the base receive address
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
 *  register to the devices MAC address and clearing all the other receive
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
 *  address registers to 0.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
	u32 i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
	u8 mac_addr[ETH_ALEN] = { 0 };
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
	/* Setup the receive address */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	e_dbg("Programming MAC Address into RAR[0]\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
	/* Zero out the other (rar_entry_count - 1) receive addresses */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
	e_dbg("Clearing RAR[1-%u]\n", rar_count - 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
	for (i = 1; i < rar_count; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
		hw->mac.ops.rar_set(hw, mac_addr, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
 *  e1000_check_alt_mac_addr_generic - Check for alternate MAC addr
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
 *  Checks the nvm for an alternate MAC address.  An alternate MAC address
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
 *  can be setup by pre-boot software and must be treated like a permanent
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
 *  address and must override the actual permanent MAC address. If an
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
 *  alternate MAC address is found it is programmed into RAR0, replacing
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
 *  the permanent address that was installed into RAR0 by the Si on reset.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
 *  This function will return SUCCESS unless it encounters an error while
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
 *  reading the EEPROM.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
	u32 i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
	u16 offset, nvm_alt_mac_addr_offset, nvm_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
	u8 alt_mac_addr[ETH_ALEN];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
	ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
	/* not supported on 82573 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
	if (hw->mac.type == e1000_82573)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
	ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
				 &nvm_alt_mac_addr_offset);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
	if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
		e_dbg("NVM Read Error\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
	if ((nvm_alt_mac_addr_offset == 0xFFFF) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	    (nvm_alt_mac_addr_offset == 0x0000))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
		/* There is no Alternate MAC Address */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
	if (hw->bus.func == E1000_FUNC_1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
		nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	for (i = 0; i < ETH_ALEN; i += 2) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
		offset = nvm_alt_mac_addr_offset + (i >> 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
		ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
		if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
			e_dbg("NVM Read Error\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
		alt_mac_addr[i] = (u8)(nvm_data & 0xFF);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
		alt_mac_addr[i + 1] = (u8)(nvm_data >> 8);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	/* if multicast bit is set, the alternate address will not be used */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	if (is_multicast_ether_addr(alt_mac_addr)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
		e_dbg("Ignoring Alternate Mac Address with MC bit set\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
	/* We have a valid alternate MAC address, and we want to treat it the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	 * same as the normal permanent MAC address stored by the HW into the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
	 * RAR. Do this by mapping this address into RAR0.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
 *  e1000e_rar_set_generic - Set receive address register
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
 *  @addr: pointer to the receive address
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
 *  @index: receive address array register
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
 *  Sets the receive address array register at index to the address passed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
 *  in by addr.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
void e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	u32 rar_low, rar_high;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	/* HW expects these in little endian so we reverse the byte order
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
	 * from network order (big endian) to little endian
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
	rar_low = ((u32)addr[0] | ((u32)addr[1] << 8) |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
		   ((u32)addr[2] << 16) | ((u32)addr[3] << 24));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
	rar_high = ((u32)addr[4] | ((u32)addr[5] << 8));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
	/* If MAC address zero, no need to set the AV bit */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	if (rar_low || rar_high)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
		rar_high |= E1000_RAH_AV;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
	/* Some bridges will combine consecutive 32-bit writes into
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	 * a single burst write, which will malfunction on some parts.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	 * The flushes avoid this.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	ew32(RAL(index), rar_low);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	ew32(RAH(index), rar_high);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
 *  e1000_hash_mc_addr - Generate a multicast hash value
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
 *  @mc_addr: pointer to a multicast address
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
 *  Generates a multicast address hash value which is used to determine
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
 *  the multicast filter table array address and new table value.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	u32 hash_value, hash_mask;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	u8 bit_shift = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	/* Register count multiplied by bits per register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	/* For a mc_filter_type of 0, bit_shift is the number of left-shifts
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	 * where 0xFF would still fall within the hash mask.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	while (hash_mask >> bit_shift != 0xFF)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
		bit_shift++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	/* The portion of the address that is used for the hash table
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	 * is determined by the mc_filter_type setting.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	 * The algorithm is such that there is a total of 8 bits of shifting.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	 * The bit_shift for a mc_filter_type of 0 represents the number of
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	 * left-shifts where the MSB of mc_addr[5] would still fall within
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	 * the hash_mask.  Case 0 does this exactly.  Since there are a total
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	 * of 8 bits of shifting, then mc_addr[4] will shift right the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	 * remaining number of bits. Thus 8 - bit_shift.  The rest of the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	 * cases are a variation of this algorithm...essentially raising the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	 * number of bits to shift mc_addr[5] left, while still keeping the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	 * 8-bit shifting total.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	 * For example, given the following Destination MAC Address and an
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	 * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	 * we can see that the bit_shift for case 0 is 4.  These are the hash
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	 * values resulting from each mc_filter_type...
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	 * [0] [1] [2] [3] [4] [5]
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	 * 01  AA  00  12  34  56
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	 * LSB           MSB
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	 * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	 * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	 * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	 * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	switch (hw->mac.mc_filter_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	case 0:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	case 1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
		bit_shift += 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	case 2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
		bit_shift += 2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	case 3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
		bit_shift += 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
				   (((u16)mc_addr[5]) << bit_shift)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	return hash_value;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
 *  e1000e_update_mc_addr_list_generic - Update Multicast addresses
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
 *  @mc_addr_list: array of multicast addresses to program
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
 *  @mc_addr_count: number of multicast addresses to program
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
 *  Updates entire Multicast Table Array.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
 *  The caller must have a packed mc_addr_list of multicast addresses.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
					u8 *mc_addr_list, u32 mc_addr_count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	u32 hash_value, hash_bit, hash_reg;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	/* clear mta_shadow */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	/* update mta_shadow from mc_addr_list */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	for (i = 0; (u32)i < mc_addr_count; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
		hash_bit = hash_value & 0x1F;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		mc_addr_list += (ETH_ALEN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	/* replace the entire MTA table */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
 *  e1000e_clear_hw_cntrs_base - Clear base hardware counters
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
 *  Clears the base hardware counters by reading the counter registers.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	er32(CRCERRS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	er32(SYMERRS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	er32(MPC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	er32(SCC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	er32(ECOL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	er32(MCC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	er32(LATECOL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
	er32(COLC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	er32(DC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
	er32(SEC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
	er32(RLEC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	er32(XONRXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	er32(XONTXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
	er32(XOFFRXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	er32(XOFFTXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
	er32(FCRUC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
	er32(GPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
	er32(BPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
	er32(MPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	er32(GPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	er32(GORCL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
	er32(GORCH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	er32(GOTCL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	er32(GOTCH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	er32(RNBC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	er32(RUC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
	er32(RFC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	er32(ROC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	er32(RJC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	er32(TORL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	er32(TORH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	er32(TOTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	er32(TOTH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	er32(TPR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	er32(TPT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	er32(MPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
	er32(BPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
 *  e1000e_check_for_copper_link - Check for link (Copper)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
 *  Checks to see of the link status of the hardware has changed.  If a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
 *  change in link status has been detected, then we read the PHY registers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
 *  to get the current speed/duplex if link exists.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	struct e1000_mac_info *mac = &hw->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	bool link;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	/* We only want to go out to the PHY registers to see if Auto-Neg
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	 * has completed and/or if our link status has changed.  The
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	 * get_link_status flag is set upon receiving a Link Status
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
	 * Change or Rx Sequence Error interrupt.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	if (!mac->get_link_status)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	/* First we want to see if the MII Status Register reports
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	 * link.  If so, then we want to get the current speed/duplex
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	 * of the PHY.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
	if (!link)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		return 0;	/* No link detected */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	mac->get_link_status = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	/* Check if there was DownShift, must be checked
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	 * immediately after link-up
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	e1000e_check_downshift(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	/* If we are forcing speed/duplex, then we simply return since
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	 * we have already determined whether we have link or not.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	if (!mac->autoneg)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
		return -E1000_ERR_CONFIG;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	/* Auto-Neg is enabled.  Auto Speed Detection takes care
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	 * of MAC speed/duplex configuration.  So we only need to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	 * configure Collision Distance in the MAC.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	mac->ops.config_collision_dist(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	/* Configure Flow Control now that Auto-Neg has completed.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	 * First, we need to restore the desired flow control
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
	 * settings because we may have had to re-autoneg with a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
	 * different link partner.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	ret_val = e1000e_config_fc_after_link_up(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
		e_dbg("Error configuring flow control\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
	return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
 *  e1000e_check_for_fiber_link - Check for link (Fiber)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
 *  Checks for link up on the hardware.  If link is not up and we have
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
 *  a signal, then we need to force link up.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	struct e1000_mac_info *mac = &hw->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
	u32 rxcw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	u32 status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	status = er32(STATUS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	rxcw = er32(RXCW);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	/* If we don't have link (auto-negotiation failed or link partner
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	 * cannot auto-negotiate), the cable is plugged in (we have signal),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	 * and our link partner is not trying to auto-negotiate with us (we
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	 * are receiving idles or data), we need to force link up. We also
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	 * need to give auto-negotiation time to complete, in case the cable
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	 * was just plugged in. The autoneg_failed flag does this.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	if ((ctrl & E1000_CTRL_SWDPIN1) && !(status & E1000_STATUS_LU) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	    !(rxcw & E1000_RXCW_C)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		if (!mac->autoneg_failed) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
			mac->autoneg_failed = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
			return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		/* Disable auto-negotiation in the TXCW register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
		/* Force link-up and also force full-duplex. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
		ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
		/* Configure Flow Control after forcing link up. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
		ret_val = e1000e_config_fc_after_link_up(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
		if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
			e_dbg("Error configuring flow control\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
		/* If we are forcing link and we are receiving /C/ ordered
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
		 * sets, re-enable auto-negotiation in the TXCW register
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
		 * and disable forced link in the Device Control register
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
		 * in an attempt to auto-negotiate with our link partner.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		ew32(TXCW, mac->txcw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
		mac->serdes_has_link = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
 *  e1000e_check_for_serdes_link - Check for link (Serdes)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
 *  Checks for link up on the hardware.  If link is not up and we have
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
 *  a signal, then we need to force link up.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	struct e1000_mac_info *mac = &hw->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	u32 rxcw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	u32 status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
	status = er32(STATUS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	rxcw = er32(RXCW);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	/* If we don't have link (auto-negotiation failed or link partner
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	 * cannot auto-negotiate), and our link partner is not trying to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	 * auto-negotiate with us (we are receiving idles or data),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	 * we need to force link up. We also need to give auto-negotiation
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
	 * time to complete.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	if (!(status & E1000_STATUS_LU) && !(rxcw & E1000_RXCW_C)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
		if (!mac->autoneg_failed) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
			mac->autoneg_failed = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
			return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
		/* Disable auto-negotiation in the TXCW register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
		/* Force link-up and also force full-duplex. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
		ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
		/* Configure Flow Control after forcing link up. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		ret_val = e1000e_config_fc_after_link_up(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
		if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
			e_dbg("Error configuring flow control\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		/* If we are forcing link and we are receiving /C/ ordered
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
		 * sets, re-enable auto-negotiation in the TXCW register
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		 * and disable forced link in the Device Control register
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		 * in an attempt to auto-negotiate with our link partner.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		ew32(TXCW, mac->txcw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		mac->serdes_has_link = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		/* If we force link for non-auto-negotiation switch, check
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
		 * link status based on MAC synchronization for internal
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
		 * serdes media type.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		/* SYNCH bit and IV bit are sticky. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		usleep_range(10, 20);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		rxcw = er32(RXCW);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		if (rxcw & E1000_RXCW_SYNCH) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
			if (!(rxcw & E1000_RXCW_IV)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
				mac->serdes_has_link = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
				e_dbg("SERDES: Link up - forced.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
			mac->serdes_has_link = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
			e_dbg("SERDES: Link down - force failed.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	if (E1000_TXCW_ANE & er32(TXCW)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		status = er32(STATUS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		if (status & E1000_STATUS_LU) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
			/* SYNCH bit and IV bit are sticky, so reread rxcw. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
			usleep_range(10, 20);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
			rxcw = er32(RXCW);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
			if (rxcw & E1000_RXCW_SYNCH) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
				if (!(rxcw & E1000_RXCW_IV)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
					mac->serdes_has_link = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
					e_dbg("SERDES: Link up - autoneg completed successfully.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
				} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
					mac->serdes_has_link = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
					e_dbg("SERDES: Link down - invalid codewords detected in autoneg.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
				mac->serdes_has_link = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
				e_dbg("SERDES: Link down - no sync.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
			mac->serdes_has_link = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
			e_dbg("SERDES: Link down - autoneg failed\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
 *  e1000_set_default_fc_generic - Set flow control default values
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
 *  Read the EEPROM for the default values for flow control and store the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
 *  values.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	u16 nvm_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	/* Read and store word 0x0F of the EEPROM. This word contains bits
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	 * that determine the hardware's default PAUSE (flow control) mode,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	 * a bit that determines whether the HW defaults to enabling or
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	 * disabling auto-negotiation, and the direction of the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	 * SW defined pins. If there is no SW over-ride of the flow
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	 * control setting, then the variable hw->fc will
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	 * be initialized based on a value in the EEPROM.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
		e_dbg("NVM Read Error\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	if (!(nvm_data & NVM_WORD0F_PAUSE_MASK))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
		hw->fc.requested_mode = e1000_fc_none;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
	else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == NVM_WORD0F_ASM_DIR)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		hw->fc.requested_mode = e1000_fc_tx_pause;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
		hw->fc.requested_mode = e1000_fc_full;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
 *  e1000e_setup_link_generic - Setup flow control and link settings
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
 *  Determines which flow control settings to use, then configures flow
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
 *  control.  Calls the appropriate media-specific link configuration
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
 *  function.  Assuming the adapter has a valid link partner, a valid link
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
 *  should be established.  Assumes the hardware has previously been reset
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
 *  and the transmitter and receiver are not enabled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
s32 e1000e_setup_link_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	/* In the case of the phy reset being blocked, we already have a link.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	 * We do not need to set it up again.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	/* If requested flow control is set to default, set flow control
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	 * based on the EEPROM flow control settings.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	if (hw->fc.requested_mode == e1000_fc_default) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		ret_val = e1000_set_default_fc_generic(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	/* Save off the requested flow control mode for use later.  Depending
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
	 * on the link partner's capabilities, we may or may not use this mode.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	hw->fc.current_mode = hw->fc.requested_mode;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	/* Call the necessary media_type subroutine to configure the link. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	ret_val = hw->mac.ops.setup_physical_interface(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	/* Initialize the flow control address, type, and PAUSE timer
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	 * registers to their default values.  This is done even if flow
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	 * control is disabled, because it does not hurt anything to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	 * initialize these registers.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	e_dbg("Initializing the Flow Control address, type and timer regs\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	ew32(FCT, FLOW_CONTROL_TYPE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	ew32(FCTTV, hw->fc.pause_time);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	return e1000e_set_fc_watermarks(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
 *  e1000_commit_fc_settings_generic - Configure flow control
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
 *  Write the flow control settings to the Transmit Config Word Register (TXCW)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
 *  base on the flow control settings in e1000_mac_info.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	struct e1000_mac_info *mac = &hw->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	u32 txcw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	/* Check for a software override of the flow control settings, and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	 * setup the device accordingly.  If auto-negotiation is enabled, then
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	 * software will have to set the "PAUSE" bits to the correct value in
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	 * the Transmit Config Word Register (TXCW) and re-start auto-
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	 * negotiation.  However, if auto-negotiation is disabled, then
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	 * software will have to manually configure the two flow control enable
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	 * bits in the CTRL register.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	 * The possible values of the "fc" parameter are:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	 *      0:  Flow control is completely disabled
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	 *      1:  Rx flow control is enabled (we can receive pause frames,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	 *          but not send pause frames).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	 *      2:  Tx flow control is enabled (we can send pause frames but we
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	 *          do not support receiving pause frames).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	switch (hw->fc.current_mode) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	case e1000_fc_none:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
		/* Flow control completely disabled by a software over-ride. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	case e1000_fc_rx_pause:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		/* Rx Flow control is enabled and Tx Flow control is disabled
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
		 * by a software over-ride. Since there really isn't a way to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		 * advertise that we are capable of Rx Pause ONLY, we will
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
		 * advertise that we support both symmetric and asymmetric Rx
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
		 * PAUSE.  Later, we will disable the adapter's ability to send
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
		 * PAUSE frames.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	case e1000_fc_tx_pause:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		/* Tx Flow control is enabled, and Rx Flow control is disabled,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
		 * by a software over-ride.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	case e1000_fc_full:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		/* Flow control (both Rx and Tx) is enabled by a software
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
		 * over-ride.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
		e_dbg("Flow control param set incorrectly\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		return -E1000_ERR_CONFIG;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	ew32(TXCW, txcw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	mac->txcw = txcw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
 *  e1000_poll_fiber_serdes_link_generic - Poll for link up
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
 *  Polls for link up by reading the status register, if link fails to come
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
 *  up with auto-negotiation, then the link is forced if a signal is detected.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	struct e1000_mac_info *mac = &hw->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	u32 i, status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	/* If we have a signal (the cable is plugged in, or assumed true for
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	 * serdes media) then poll for a "Link-Up" indication in the Device
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	 * Status Register.  Time-out if a link isn't seen in 500 milliseconds
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	 * seconds (Auto-negotiation should complete in less than 500
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
	 * milliseconds even if the other end is doing it in SW).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
		usleep_range(10000, 20000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
		status = er32(STATUS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		if (status & E1000_STATUS_LU)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	if (i == FIBER_LINK_UP_LIMIT) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
		e_dbg("Never got a valid link from auto-neg!!!\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
		mac->autoneg_failed = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		/* AutoNeg failed to achieve a link, so we'll call
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
		 * mac->check_for_link. This routine will force the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
		 * link up if we detect a signal. This will allow us to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		 * communicate with non-autonegotiating link partners.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
		ret_val = mac->ops.check_for_link(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
		if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
			e_dbg("Error while checking for link\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
		mac->autoneg_failed = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
		mac->autoneg_failed = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
		e_dbg("Valid Link Found\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
 *  e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
 *  Configures collision distance and flow control for fiber and serdes
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
 *  links.  Upon successful setup, poll for link.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	/* Take the link out of reset */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	ctrl &= ~E1000_CTRL_LRST;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	hw->mac.ops.config_collision_dist(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	ret_val = e1000_commit_fc_settings_generic(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	/* Since auto-negotiation is enabled, take the link out of reset (the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	 * link will be in reset, because we previously reset the chip). This
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	 * will restart auto-negotiation.  If auto-negotiation is successful
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	 * then the link-up status bit will be set and the flow control enable
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	 * bits (RFCE and TFCE) will be set according to their negotiated value.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	e_dbg("Auto-negotiation enabled\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	usleep_range(1000, 2000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	/* For these adapters, the SW definable pin 1 is set when the optics
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	 * detect a signal.  If we have a signal, then poll for a "Link-Up"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	 * indication.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	if (hw->phy.media_type == e1000_media_type_internal_serdes ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	    (er32(CTRL) & E1000_CTRL_SWDPIN1)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		ret_val = e1000_poll_fiber_serdes_link_generic(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
		e_dbg("No signal detected\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
 *  e1000e_config_collision_dist_generic - Configure collision distance
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
 *  Configures the collision distance to the default value and is used
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
 *  during link setup.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
void e1000e_config_collision_dist_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	u32 tctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	tctl = er32(TCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	tctl &= ~E1000_TCTL_COLD;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	ew32(TCTL, tctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
 *  e1000e_set_fc_watermarks - Set flow control high/low watermarks
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
 *  Sets the flow control high/low threshold (watermark) registers.  If
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
 *  flow control XON frame transmission is enabled, then set XON frame
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
 *  transmission as well.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	u32 fcrtl = 0, fcrth = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	/* Set the flow control receive threshold registers.  Normally,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	 * these registers will be set to a default threshold that may be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	 * adjusted later by the driver's runtime code.  However, if the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	 * ability to transmit pause frames is not enabled, then these
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	 * registers will be set to 0.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	if (hw->fc.current_mode & e1000_fc_tx_pause) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
		/* We need to set up the Receive Threshold high and low water
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		 * marks as well as (optionally) enabling the transmission of
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
		 * XON frames.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
		fcrtl = hw->fc.low_water;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		if (hw->fc.send_xon)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
			fcrtl |= E1000_FCRTL_XONE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		fcrth = hw->fc.high_water;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	ew32(FCRTL, fcrtl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	ew32(FCRTH, fcrth);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
 *  e1000e_force_mac_fc - Force the MAC's flow control settings
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
 *  Force the MAC's flow control settings.  Sets the TFCE and RFCE bits in the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
 *  device control register to reflect the adapter settings.  TFCE and RFCE
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
 *  need to be explicitly set by software when a copper PHY is used because
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
 *  autonegotiation is managed by the PHY rather than the MAC.  Software must
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
 *  also configure these bits when link is forced on a fiber connection.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
s32 e1000e_force_mac_fc(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	/* Because we didn't get link via the internal auto-negotiation
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	 * mechanism (we either forced link or we got link via PHY
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	 * auto-neg), we have to manually enable/disable transmit an
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	 * receive flow control.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	 * The "Case" statement below enables/disable flow control
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	 * according to the "hw->fc.current_mode" parameter.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	 * The possible values of the "fc" parameter are:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	 *      0:  Flow control is completely disabled
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	 *      1:  Rx flow control is enabled (we can receive pause
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	 *          frames but not send pause frames).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	 *      2:  Tx flow control is enabled (we can send pause frames
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
	 *          frames but we do not receive pause frames).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	 *      3:  Both Rx and Tx flow control (symmetric) is enabled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	 *  other:  No other values should be possible at this point.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	switch (hw->fc.current_mode) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	case e1000_fc_none:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	case e1000_fc_rx_pause:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		ctrl &= (~E1000_CTRL_TFCE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		ctrl |= E1000_CTRL_RFCE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	case e1000_fc_tx_pause:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
		ctrl &= (~E1000_CTRL_RFCE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
		ctrl |= E1000_CTRL_TFCE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	case e1000_fc_full:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		e_dbg("Flow control param set incorrectly\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		return -E1000_ERR_CONFIG;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
 *  e1000e_config_fc_after_link_up - Configures flow control after link
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
 *  Checks the status of auto-negotiation after link up to ensure that the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
 *  speed and duplex were not forced.  If the link needed to be forced, then
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
 *  flow control needs to be forced also.  If auto-negotiation is enabled
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
 *  and did not fail, then we configure flow control based on our link
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
 *  partner.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	struct e1000_mac_info *mac = &hw->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	s32 ret_val = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	u16 speed, duplex;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	/* Check for the case where we have fiber media and auto-neg failed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	 * so we had to force link.  In this case, we need to force the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	 * configuration of the MAC to match the "fc" parameter.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	if (mac->autoneg_failed) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
		if (hw->phy.media_type == e1000_media_type_fiber ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		    hw->phy.media_type == e1000_media_type_internal_serdes)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
			ret_val = e1000e_force_mac_fc(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		if (hw->phy.media_type == e1000_media_type_copper)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
			ret_val = e1000e_force_mac_fc(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
		e_dbg("Error forcing flow control settings\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	/* Check for the case where we have copper media and auto-neg is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	 * enabled.  In this case, we need to check and see if Auto-Neg
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	 * has completed, and if so, how the PHY and link partner has
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	 * flow control configured.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
		/* Read the MII Status Register and check to see if AutoNeg
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		 * has completed.  We read this twice because this reg has
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		 * some "sticky" (latched) bits.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		ret_val = e1e_rphy(hw, MII_BMSR, &mii_status_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		ret_val = e1e_rphy(hw, MII_BMSR, &mii_status_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		if (!(mii_status_reg & BMSR_ANEGCOMPLETE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
			e_dbg("Copper PHY and Auto Neg has not completed.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
		/* The AutoNeg process has completed, so we now need to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
		 * read both the Auto Negotiation Advertisement
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		 * Register (Address 4) and the Auto_Negotiation Base
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		 * Page Ability Register (Address 5) to determine how
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		 * flow control was negotiated.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
		ret_val = e1e_rphy(hw, MII_ADVERTISE, &mii_nway_adv_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
		if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
		ret_val = e1e_rphy(hw, MII_LPA, &mii_nway_lp_ability_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
		if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
		/* Two bits in the Auto Negotiation Advertisement Register
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
		 * (Address 4) and two bits in the Auto Negotiation Base
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
		 * Page Ability Register (Address 5) determine flow control
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
		 * for both the PHY and the link partner.  The following
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
		 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
		 * 1999, describes these PAUSE resolution bits and how flow
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
		 * control is determined based upon these settings.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		 * NOTE:  DC = Don't Care
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
		 *   LOCAL DEVICE  |   LINK PARTNER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		 *-------|---------|-------|---------|--------------------
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		 *   0   |    0    |  DC   |   DC    | e1000_fc_none
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
		 *   0   |    1    |   0   |   DC    | e1000_fc_none
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		 *   0   |    1    |   1   |    0    | e1000_fc_none
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		 *   1   |    0    |   0   |   DC    | e1000_fc_none
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		 *   1   |   DC    |   1   |   DC    | e1000_fc_full
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		 *   1   |    1    |   0   |    0    | e1000_fc_none
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		 * Are both PAUSE bits set to 1?  If so, this implies
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		 * Symmetric Flow Control is enabled at both ends.  The
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
		 * ASM_DIR bits are irrelevant per the spec.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
		 * For Symmetric Flow Control:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
		 *   LOCAL DEVICE  |   LINK PARTNER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		 *-------|---------|-------|---------|--------------------
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
		 *   1   |   DC    |   1   |   DC    | E1000_fc_full
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
		if ((mii_nway_adv_reg & ADVERTISE_PAUSE_CAP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
		    (mii_nway_lp_ability_reg & LPA_PAUSE_CAP)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
			/* Now we need to check if the user selected Rx ONLY
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
			 * of pause frames.  In this case, we had to advertise
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
			 * FULL flow control because we could not advertise Rx
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
			 * ONLY. Hence, we must now check to see if we need to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
			 * turn OFF the TRANSMISSION of PAUSE frames.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
			if (hw->fc.requested_mode == e1000_fc_full) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
				hw->fc.current_mode = e1000_fc_full;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
				e_dbg("Flow Control = FULL.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
				hw->fc.current_mode = e1000_fc_rx_pause;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
				e_dbg("Flow Control = Rx PAUSE frames only.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		/* For receiving PAUSE frames ONLY.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
		 *   LOCAL DEVICE  |   LINK PARTNER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		 *-------|---------|-------|---------|--------------------
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
		else if (!(mii_nway_adv_reg & ADVERTISE_PAUSE_CAP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
			 (mii_nway_adv_reg & ADVERTISE_PAUSE_ASYM) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
			 (mii_nway_lp_ability_reg & LPA_PAUSE_CAP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
			 (mii_nway_lp_ability_reg & LPA_PAUSE_ASYM)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
			hw->fc.current_mode = e1000_fc_tx_pause;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
			e_dbg("Flow Control = Tx PAUSE frames only.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		/* For transmitting PAUSE frames ONLY.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		 *   LOCAL DEVICE  |   LINK PARTNER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		 *-------|---------|-------|---------|--------------------
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		else if ((mii_nway_adv_reg & ADVERTISE_PAUSE_CAP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
			 (mii_nway_adv_reg & ADVERTISE_PAUSE_ASYM) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
			 !(mii_nway_lp_ability_reg & LPA_PAUSE_CAP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
			 (mii_nway_lp_ability_reg & LPA_PAUSE_ASYM)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
			hw->fc.current_mode = e1000_fc_rx_pause;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
			e_dbg("Flow Control = Rx PAUSE frames only.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
			/* Per the IEEE spec, at this point flow control
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
			 * should be disabled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
			hw->fc.current_mode = e1000_fc_none;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
			e_dbg("Flow Control = NONE.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
		/* Now we need to do one last check...  If we auto-
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		 * negotiated to HALF DUPLEX, flow control should not be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		 * enabled per IEEE 802.3 spec.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
		if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
			e_dbg("Error getting link speed and duplex\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		if (duplex == HALF_DUPLEX)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
			hw->fc.current_mode = e1000_fc_none;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
		/* Now we call a subroutine to actually force the MAC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
		 * controller to use the correct flow control settings.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
		ret_val = e1000e_force_mac_fc(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
		if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
			e_dbg("Error forcing flow control settings\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	/* Check for the case where we have SerDes media and auto-neg is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	 * enabled.  In this case, we need to check and see if Auto-Neg
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	 * has completed, and if so, how the PHY and link partner has
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
	 * flow control configured.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
	if ((hw->phy.media_type == e1000_media_type_internal_serdes) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	    mac->autoneg) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		/* Read the PCS_LSTS and check to see if AutoNeg
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		 * has completed.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		pcs_status_reg = er32(PCS_LSTAT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
		if (!(pcs_status_reg & E1000_PCS_LSTS_AN_COMPLETE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
			e_dbg("PCS Auto Neg has not completed.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
		/* The AutoNeg process has completed, so we now need to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		 * read both the Auto Negotiation Advertisement
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
		 * Register (PCS_ANADV) and the Auto_Negotiation Base
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
		 * Page Ability Register (PCS_LPAB) to determine how
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		 * flow control was negotiated.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
		pcs_adv_reg = er32(PCS_ANADV);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
		pcs_lp_ability_reg = er32(PCS_LPAB);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		/* Two bits in the Auto Negotiation Advertisement Register
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		 * (PCS_ANADV) and two bits in the Auto Negotiation Base
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		 * Page Ability Register (PCS_LPAB) determine flow control
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		 * for both the PHY and the link partner.  The following
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
		 * 1999, describes these PAUSE resolution bits and how flow
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		 * control is determined based upon these settings.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		 * NOTE:  DC = Don't Care
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		 *   LOCAL DEVICE  |   LINK PARTNER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		 *-------|---------|-------|---------|--------------------
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		 *   0   |    0    |  DC   |   DC    | e1000_fc_none
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		 *   0   |    1    |   0   |   DC    | e1000_fc_none
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		 *   0   |    1    |   1   |    0    | e1000_fc_none
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
		 *   1   |    0    |   0   |   DC    | e1000_fc_none
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		 *   1   |   DC    |   1   |   DC    | e1000_fc_full
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		 *   1   |    1    |   0   |    0    | e1000_fc_none
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		 * Are both PAUSE bits set to 1?  If so, this implies
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		 * Symmetric Flow Control is enabled at both ends.  The
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
		 * ASM_DIR bits are irrelevant per the spec.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
		 * For Symmetric Flow Control:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		 *   LOCAL DEVICE  |   LINK PARTNER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
		 *-------|---------|-------|---------|--------------------
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
		 *   1   |   DC    |   1   |   DC    | e1000_fc_full
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
		if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
		    (pcs_lp_ability_reg & E1000_TXCW_PAUSE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
			/* Now we need to check if the user selected Rx ONLY
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
			 * of pause frames.  In this case, we had to advertise
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
			 * FULL flow control because we could not advertise Rx
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
			 * ONLY. Hence, we must now check to see if we need to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
			 * turn OFF the TRANSMISSION of PAUSE frames.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
			if (hw->fc.requested_mode == e1000_fc_full) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
				hw->fc.current_mode = e1000_fc_full;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
				e_dbg("Flow Control = FULL.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
				hw->fc.current_mode = e1000_fc_rx_pause;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
				e_dbg("Flow Control = Rx PAUSE frames only.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
		/* For receiving PAUSE frames ONLY.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
		 *   LOCAL DEVICE  |   LINK PARTNER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
		 *-------|---------|-------|---------|--------------------
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
		else if (!(pcs_adv_reg & E1000_TXCW_PAUSE) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
			 (pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
			 (pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
			 (pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
			hw->fc.current_mode = e1000_fc_tx_pause;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
			e_dbg("Flow Control = Tx PAUSE frames only.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
		/* For transmitting PAUSE frames ONLY.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
		 *   LOCAL DEVICE  |   LINK PARTNER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
		 *-------|---------|-------|---------|--------------------
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		else if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
			 (pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
			 !(pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
			 (pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
			hw->fc.current_mode = e1000_fc_rx_pause;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
			e_dbg("Flow Control = Rx PAUSE frames only.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
			/* Per the IEEE spec, at this point flow control
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
			 * should be disabled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
			hw->fc.current_mode = e1000_fc_none;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
			e_dbg("Flow Control = NONE.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
		/* Now we call a subroutine to actually force the MAC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
		 * controller to use the correct flow control settings.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
		pcs_ctrl_reg = er32(PCS_LCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
		pcs_ctrl_reg |= E1000_PCS_LCTL_FORCE_FCTRL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
		ew32(PCS_LCTL, pcs_ctrl_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
		ret_val = e1000e_force_mac_fc(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
		if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
			e_dbg("Error forcing flow control settings\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
			return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
 *  e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
 *  @speed: stores the current speed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
 *  @duplex: stores the current duplex
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
 *  Read the status register for the current speed/duplex and store the current
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
 *  speed and duplex for copper connections.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
				       u16 *duplex)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	u32 status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	status = er32(STATUS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	if (status & E1000_STATUS_SPEED_1000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
		*speed = SPEED_1000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	else if (status & E1000_STATUS_SPEED_100)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
		*speed = SPEED_100;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
		*speed = SPEED_10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	if (status & E1000_STATUS_FD)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
		*duplex = FULL_DUPLEX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
		*duplex = HALF_DUPLEX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	e_dbg("%u Mbps, %s Duplex\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	      *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	      *duplex == FULL_DUPLEX ? "Full" : "Half");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
 *  e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
 *  @speed: stores the current speed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
 *  @duplex: stores the current duplex
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
 *  Sets the speed and duplex to gigabit full duplex (the only possible option)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
 *  for fiber/serdes links.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw __always_unused
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
					     *hw, u16 *speed, u16 *duplex)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	*speed = SPEED_1000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	*duplex = FULL_DUPLEX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
 *  e1000e_get_hw_semaphore - Acquire hardware semaphore
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
 *  Acquire the HW semaphore to access the PHY or NVM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
s32 e1000e_get_hw_semaphore(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	u32 swsm;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	s32 timeout = hw->nvm.word_size + 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	s32 i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	/* Get the SW semaphore */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	while (i < timeout) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
		swsm = er32(SWSM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		if (!(swsm & E1000_SWSM_SMBI))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
		usleep_range(50, 100);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
		i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
	if (i == timeout) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
		e_dbg("Driver can't access device - SMBI bit is set.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
		return -E1000_ERR_NVM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	/* Get the FW semaphore. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
	for (i = 0; i < timeout; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
		swsm = er32(SWSM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
		ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
		/* Semaphore acquired if bit latched */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
		if (er32(SWSM) & E1000_SWSM_SWESMBI)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		usleep_range(50, 100);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	if (i == timeout) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		/* Release semaphores */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
		e1000e_put_hw_semaphore(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		e_dbg("Driver can't access the NVM\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		return -E1000_ERR_NVM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
 *  e1000e_put_hw_semaphore - Release hardware semaphore
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
 *  Release hardware semaphore used to access the PHY or NVM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
void e1000e_put_hw_semaphore(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	u32 swsm;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
	swsm = er32(SWSM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
	swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
	ew32(SWSM, swsm);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
 *  e1000e_get_auto_rd_done - Check for auto read completion
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
 *  Check EEPROM for Auto Read done bit.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
s32 e1000e_get_auto_rd_done(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	s32 i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	while (i < AUTO_READ_DONE_TIMEOUT) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
		if (er32(EECD) & E1000_EECD_AUTO_RD)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
		usleep_range(1000, 2000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
		i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	if (i == AUTO_READ_DONE_TIMEOUT) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
		e_dbg("Auto read by HW from NVM has not completed.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
		return -E1000_ERR_RESET;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
 *  e1000e_valid_led_default - Verify a valid default LED config
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
 *  @data: pointer to the NVM (EEPROM)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
 *  Read the EEPROM for the current default LED configuration.  If the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
 *  LED configuration is not valid, set to a valid LED configuration.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
		e_dbg("NVM Read Error\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
		*data = ID_LED_DEFAULT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
 *  e1000e_id_led_init_generic -
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
s32 e1000e_id_led_init_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	struct e1000_mac_info *mac = &hw->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	const u32 ledctl_mask = 0x000000FF;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	u16 data, i, temp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	const u16 led_mask = 0x0F;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
	ret_val = hw->nvm.ops.valid_led_default(hw, &data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	mac->ledctl_default = er32(LEDCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
	mac->ledctl_mode1 = mac->ledctl_default;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	mac->ledctl_mode2 = mac->ledctl_default;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	for (i = 0; i < 4; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
		temp = (data >> (i << 2)) & led_mask;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
		switch (temp) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		case ID_LED_ON1_DEF2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
		case ID_LED_ON1_ON2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
		case ID_LED_ON1_OFF2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
			mac->ledctl_mode1 |= ledctl_on << (i << 3);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		case ID_LED_OFF1_DEF2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
		case ID_LED_OFF1_ON2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
		case ID_LED_OFF1_OFF2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
			mac->ledctl_mode1 |= ledctl_off << (i << 3);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
			/* Do nothing */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
		switch (temp) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		case ID_LED_DEF1_ON2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
		case ID_LED_ON1_ON2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
		case ID_LED_OFF1_ON2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
			mac->ledctl_mode2 |= ledctl_on << (i << 3);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
		case ID_LED_DEF1_OFF2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
		case ID_LED_ON1_OFF2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
		case ID_LED_OFF1_OFF2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
			mac->ledctl_mode2 |= ledctl_off << (i << 3);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
		default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
			/* Do nothing */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
 *  e1000e_setup_led_generic - Configures SW controllable LED
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
 *  This prepares the SW controllable LED for use and saves the current state
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
 *  of the LED so it can be later restored.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
s32 e1000e_setup_led_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	u32 ledctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	if (hw->mac.ops.setup_led != e1000e_setup_led_generic)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
		return -E1000_ERR_CONFIG;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
	if (hw->phy.media_type == e1000_media_type_fiber) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		ledctl = er32(LEDCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		hw->mac.ledctl_default = ledctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
		/* Turn off LED0 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		ledctl &= ~(E1000_LEDCTL_LED0_IVRT | E1000_LEDCTL_LED0_BLINK |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
			    E1000_LEDCTL_LED0_MODE_MASK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
		ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
			   E1000_LEDCTL_LED0_MODE_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		ew32(LEDCTL, ledctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	} else if (hw->phy.media_type == e1000_media_type_copper) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		ew32(LEDCTL, hw->mac.ledctl_mode1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
 *  e1000e_cleanup_led_generic - Set LED config to default operation
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
 *  Remove the current LED configuration and set the LED configuration
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
 *  to the default value, saved from the EEPROM.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
	ew32(LEDCTL, hw->mac.ledctl_default);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
 *  e1000e_blink_led_generic - Blink LED
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
 *  Blink the LEDs which are set to be on.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
s32 e1000e_blink_led_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	u32 ledctl_blink = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	u32 i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	if (hw->phy.media_type == e1000_media_type_fiber) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		/* always blink LED0 for PCI-E fiber */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		ledctl_blink = E1000_LEDCTL_LED0_BLINK |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		    (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		/* Set the blink bit for each LED that's "on" (0x0E)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
		 * (or "off" if inverted) in ledctl_mode2.  The blink
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		 * logic in hardware only works when mode is set to "on"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
		 * so it must be changed accordingly when the mode is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
		 * "off" and inverted.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		ledctl_blink = hw->mac.ledctl_mode2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		for (i = 0; i < 32; i += 8) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
			u32 mode = (hw->mac.ledctl_mode2 >> i) &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
			    E1000_LEDCTL_LED0_MODE_MASK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
			u32 led_default = hw->mac.ledctl_default >> i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
			if ((!(led_default & E1000_LEDCTL_LED0_IVRT) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
			     (mode == E1000_LEDCTL_MODE_LED_ON)) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
			    ((led_default & E1000_LEDCTL_LED0_IVRT) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
			     (mode == E1000_LEDCTL_MODE_LED_OFF))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
				ledctl_blink &=
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
				    ~(E1000_LEDCTL_LED0_MODE_MASK << i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
						 E1000_LEDCTL_MODE_LED_ON) << i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	ew32(LEDCTL, ledctl_blink);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
 *  e1000e_led_on_generic - Turn LED on
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
 *  Turn LED on.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
s32 e1000e_led_on_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
	u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
	switch (hw->phy.media_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
	case e1000_media_type_fiber:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		ctrl &= ~E1000_CTRL_SWDPIN0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
		ctrl |= E1000_CTRL_SWDPIO0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
		ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	case e1000_media_type_copper:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		ew32(LEDCTL, hw->mac.ledctl_mode2);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
 *  e1000e_led_off_generic - Turn LED off
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
 *  Turn LED off.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
s32 e1000e_led_off_generic(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
	switch (hw->phy.media_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	case e1000_media_type_fiber:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
		ctrl |= E1000_CTRL_SWDPIN0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		ctrl |= E1000_CTRL_SWDPIO0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
		ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
	case e1000_media_type_copper:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		ew32(LEDCTL, hw->mac.ledctl_mode1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
 *  e1000e_set_pcie_no_snoop - Set PCI-express capabilities
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
 *  @no_snoop: bitmap of snoop events
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
 *  Set the PCI-express register to snoop for events enabled in 'no_snoop'.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	u32 gcr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	if (no_snoop) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		gcr = er32(GCR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
		gcr &= ~(PCIE_NO_SNOOP_ALL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
		gcr |= no_snoop;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		ew32(GCR, gcr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
 *  e1000e_disable_pcie_master - Disables PCI-express master access
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
 *  Returns 0 if successful, else returns -10
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
 *  (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
 *  the master requests to be disabled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
 *  Disables PCI-Express master access and verifies there are no pending
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
 *  requests.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
s32 e1000e_disable_pcie_master(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	s32 timeout = MASTER_DISABLE_TIMEOUT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
	while (timeout) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		if (!(er32(STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		usleep_range(100, 200);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		timeout--;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	if (!timeout) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
		e_dbg("Master requests are pending.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		return -E1000_ERR_MASTER_REQUESTS_PENDING;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
 *  e1000e_reset_adaptive - Reset Adaptive Interframe Spacing
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
 *  Reset the Adaptive Interframe Spacing throttle to default values.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
void e1000e_reset_adaptive(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	struct e1000_mac_info *mac = &hw->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	if (!mac->adaptive_ifs) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
		e_dbg("Not in Adaptive IFS mode!\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	mac->current_ifs_val = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
	mac->ifs_min_val = IFS_MIN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
	mac->ifs_max_val = IFS_MAX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
	mac->ifs_step_size = IFS_STEP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	mac->ifs_ratio = IFS_RATIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	mac->in_ifs_mode = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	ew32(AIT, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
 *  e1000e_update_adaptive - Update Adaptive Interframe Spacing
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
 *  @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
 *  Update the Adaptive Interframe Spacing Throttle value based on the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
 *  time between transmitted packets and time between collisions.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
void e1000e_update_adaptive(struct e1000_hw *hw)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	struct e1000_mac_info *mac = &hw->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
	if (!mac->adaptive_ifs) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		e_dbg("Not in Adaptive IFS mode!\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		if (mac->tx_packet_delta > MIN_NUM_XMITS) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
			mac->in_ifs_mode = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
			if (mac->current_ifs_val < mac->ifs_max_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
				if (!mac->current_ifs_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
					mac->current_ifs_val = mac->ifs_min_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
				else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
					mac->current_ifs_val +=
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
					    mac->ifs_step_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
				ew32(AIT, mac->current_ifs_val);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		if (mac->in_ifs_mode &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
			mac->current_ifs_val = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
			mac->in_ifs_mode = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
			ew32(AIT, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
}