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