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