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