devices/e1000e/lib-3.2-ethercat.c
author Knud Baastrup <kba@deif.com>
Tue, 14 Apr 2015 10:12:55 -0400
changeset 2625 e25af8bd3957
parent 2406 fee219bb31a9
permissions -rw-r--r--
Eoe mac address now derived from unique mac.
The EoE MAC address is now derived from the NIC part of the first global
unique MAC address of the linked list of available network interfaces or
otherwise the MAC address used by the EtherCAT master. The EoE MAC address
will get the format 02:NIC:NIC:NIC:RP:RP where NIC comes from the unique MAC
address (if available) and RP is the ring position of the EoE slave.
2406
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2011 Intel Corporation.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000-3.2-ethercat.h"
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
enum e1000_mng_mode {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
	e1000_mng_mode_none = 0,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
	e1000_mng_mode_asf,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
	e1000_mng_mode_pt,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
	e1000_mng_mode_ipmi,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
	e1000_mng_mode_host_if_only
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
};
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#define E1000_FACTPS_MNGCG		0x20000000
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
/* Intel(R) Active Management Technology signature */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#define E1000_IAMT_SIGNATURE		0x544D4149
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
 *  e1000e_get_bus_info_pcie - Get PCIe bus information
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
 *  Determines and stores the system bus information for a particular
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
 *  network interface.  The following bus information is determined and stored:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
 *  bus speed, bus width, type (PCIe), and PCIe function.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	struct e1000_bus_info *bus = &hw->bus;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	struct e1000_adapter *adapter = hw->adapter;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	u16 pcie_link_status, cap_offset;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	cap_offset = adapter->pdev->pcie_cap;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	if (!cap_offset) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
		bus->width = e1000_bus_width_unknown;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
		pci_read_config_word(adapter->pdev,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
				     cap_offset + PCIE_LINK_STATUS,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
				     &pcie_link_status);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
		bus->width = (enum e1000_bus_width)((pcie_link_status &
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
						     PCIE_LINK_WIDTH_MASK) >>
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
						    PCIE_LINK_WIDTH_SHIFT);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	mac->ops.set_lan_id(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
 *  e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
 *  Determines the LAN function id by reading memory-mapped registers
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
 *  and swaps the port value if requested.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	struct e1000_bus_info *bus = &hw->bus;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
	u32 reg;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
	 * The status register reports the correct function number
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	 * for the device regardless of function swap state.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	reg = er32(STATUS);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
	bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
 *  e1000_set_lan_id_single_port - Set LAN id for a single port device
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
 *  Sets the LAN function id to zero for a single port device.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
void e1000_set_lan_id_single_port(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	struct e1000_bus_info *bus = &hw->bus;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	bus->func = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
 *  e1000_clear_vfta_generic - Clear VLAN filter table
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
 *  Clears the register array which contains the VLAN filter table by
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
 *  setting all the values to 0.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
void e1000_clear_vfta_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	u32 offset;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
		e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
 *  e1000_write_vfta_generic - Write value to VLAN filter table
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
 *  @offset: register offset in VLAN filter table
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
 *  @value: register value written to VLAN filter table
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
 *  Writes value at the given offset in the register array which stores
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
 *  the VLAN filter table.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
	E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
	e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
 *  e1000e_init_rx_addrs - Initialize receive address's
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
 *  @rar_count: receive address registers
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
 *  Setup the receive address registers by setting the base receive address
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
 *  register to the devices MAC address and clearing all the other receive
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
 *  address registers to 0.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
	u32 i;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
	u8 mac_addr[ETH_ALEN] = {0};
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
	/* Setup the receive address */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	e_dbg("Programming MAC Address into RAR[0]\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
	e1000e_rar_set(hw, hw->mac.addr, 0);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
	/* Zero out the other (rar_entry_count - 1) receive addresses */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
	e_dbg("Clearing RAR[1-%u]\n", rar_count-1);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
	for (i = 1; i < rar_count; i++)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
		e1000e_rar_set(hw, mac_addr, i);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
 *  e1000_check_alt_mac_addr_generic - Check for alternate MAC addr
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
 *  Checks the nvm for an alternate MAC address.  An alternate MAC address
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
 *  can be setup by pre-boot software and must be treated like a permanent
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
 *  address and must override the actual permanent MAC address. If an
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
 *  alternate MAC address is found it is programmed into RAR0, replacing
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
 *  the permanent address that was installed into RAR0 by the Si on reset.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
 *  This function will return SUCCESS unless it encounters an error while
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
 *  reading the EEPROM.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
	u32 i;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
	s32 ret_val = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
	u16 offset, nvm_alt_mac_addr_offset, nvm_data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
	u8 alt_mac_addr[ETH_ALEN];
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
	ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	/* Check for LOM (vs. NIC) or one of two valid mezzanine cards */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
	if (!((nvm_data & NVM_COMPAT_LOM) ||
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
	      (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) ||
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	      (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) ||
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	      (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES)))
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	                         &nvm_alt_mac_addr_offset);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
		e_dbg("NVM Read Error\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	if ((nvm_alt_mac_addr_offset == 0xFFFF) ||
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	    (nvm_alt_mac_addr_offset == 0x0000))
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
		/* There is no Alternate MAC Address */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	if (hw->bus.func == E1000_FUNC_1)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
		nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	for (i = 0; i < ETH_ALEN; i += 2) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
		offset = nvm_alt_mac_addr_offset + (i >> 1);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
		ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
		if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
			e_dbg("NVM Read Error\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
			goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
		alt_mac_addr[i] = (u8)(nvm_data & 0xFF);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
		alt_mac_addr[i + 1] = (u8)(nvm_data >> 8);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	/* if multicast bit is set, the alternate address will not be used */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	if (is_multicast_ether_addr(alt_mac_addr)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
		e_dbg("Ignoring Alternate Mac Address with MC bit set\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	 * We have a valid alternate MAC address, and we want to treat it the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	 * same as the normal permanent MAC address stored by the HW into the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	 * RAR. Do this by mapping this address into RAR0.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	e1000e_rar_set(hw, alt_mac_addr, 0);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
out:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
	return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
 *  e1000e_rar_set - Set receive address register
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
 *  @addr: pointer to the receive address
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
 *  @index: receive address array register
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
 *  Sets the receive address array register at index to the address passed
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
 *  in by addr.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	u32 rar_low, rar_high;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	 * HW expects these in little endian so we reverse the byte order
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	 * from network order (big endian) to little endian
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	rar_low = ((u32) addr[0] |
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
		   ((u32) addr[1] << 8) |
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
		    ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	/* If MAC address zero, no need to set the AV bit */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	if (rar_low || rar_high)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
		rar_high |= E1000_RAH_AV;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	 * Some bridges will combine consecutive 32-bit writes into
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	 * a single burst write, which will malfunction on some parts.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	 * The flushes avoid this.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	ew32(RAL(index), rar_low);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	ew32(RAH(index), rar_high);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
 *  e1000_hash_mc_addr - Generate a multicast hash value
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
 *  @mc_addr: pointer to a multicast address
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
 *  Generates a multicast address hash value which is used to determine
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
 *  the multicast filter table array address and new table value.  See
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
 *  e1000_mta_set_generic()
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	u32 hash_value, hash_mask;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	u8 bit_shift = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	/* Register count multiplied by bits per register */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	 * For a mc_filter_type of 0, bit_shift is the number of left-shifts
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	 * where 0xFF would still fall within the hash mask.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	while (hash_mask >> bit_shift != 0xFF)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
		bit_shift++;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	 * The portion of the address that is used for the hash table
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	 * is determined by the mc_filter_type setting.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	 * The algorithm is such that there is a total of 8 bits of shifting.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	 * The bit_shift for a mc_filter_type of 0 represents the number of
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	 * left-shifts where the MSB of mc_addr[5] would still fall within
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
	 * the hash_mask.  Case 0 does this exactly.  Since there are a total
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	 * of 8 bits of shifting, then mc_addr[4] will shift right the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	 * remaining number of bits. Thus 8 - bit_shift.  The rest of the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	 * cases are a variation of this algorithm...essentially raising the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	 * number of bits to shift mc_addr[5] left, while still keeping the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	 * 8-bit shifting total.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	 * For example, given the following Destination MAC Address and an
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	 * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask),
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	 * we can see that the bit_shift for case 0 is 4.  These are the hash
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	 * values resulting from each mc_filter_type...
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	 * [0] [1] [2] [3] [4] [5]
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	 * 01  AA  00  12  34  56
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	 * LSB		 MSB
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	 * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	 * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	 * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	 * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
	switch (hw->mac.mc_filter_type) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	default:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	case 0:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	case 1:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
		bit_shift += 1;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	case 2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
		bit_shift += 2;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	case 3:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
		bit_shift += 4;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
				  (((u16) mc_addr[5]) << bit_shift)));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	return hash_value;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
 *  e1000e_update_mc_addr_list_generic - Update Multicast addresses
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
 *  @mc_addr_list: array of multicast addresses to program
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
 *  @mc_addr_count: number of multicast addresses to program
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
 *  Updates entire Multicast Table Array.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
 *  The caller must have a packed mc_addr_list of multicast addresses.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
					u8 *mc_addr_list, u32 mc_addr_count)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
	u32 hash_value, hash_bit, hash_reg;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
	int i;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	/* clear mta_shadow */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	/* update mta_shadow from mc_addr_list */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	for (i = 0; (u32) i < mc_addr_count; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
		hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
		hash_bit = hash_value & 0x1F;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
		mc_addr_list += (ETH_ALEN);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	/* replace the entire MTA table */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
 *  e1000e_clear_hw_cntrs_base - Clear base hardware counters
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
 *  Clears the base hardware counters by reading the counter registers.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	er32(CRCERRS);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
	er32(SYMERRS);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	er32(MPC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	er32(SCC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	er32(ECOL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	er32(MCC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	er32(LATECOL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	er32(COLC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	er32(DC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	er32(SEC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	er32(RLEC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
	er32(XONRXC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
	er32(XONTXC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
	er32(XOFFRXC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	er32(XOFFTXC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	er32(FCRUC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	er32(GPRC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
	er32(BPRC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	er32(MPRC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	er32(GPTC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	er32(GORCL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	er32(GORCH);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	er32(GOTCL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	er32(GOTCH);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	er32(RNBC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	er32(RUC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	er32(RFC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	er32(ROC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	er32(RJC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	er32(TORL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	er32(TORH);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
	er32(TOTL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	er32(TOTH);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	er32(TPR);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	er32(TPT);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
	er32(MPTC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	er32(BPTC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
 *  e1000e_check_for_copper_link - Check for link (Copper)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
 *  Checks to see of the link status of the hardware has changed.  If a
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
 *  change in link status has been detected, then we read the PHY registers
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
 *  to get the current speed/duplex if link exists.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	bool link;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	 * We only want to go out to the PHY registers to see if Auto-Neg
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	 * has completed and/or if our link status has changed.  The
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	 * get_link_status flag is set upon receiving a Link Status
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	 * Change or Rx Sequence Error interrupt.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	if (!mac->get_link_status)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
		return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
	 * First we want to see if the MII Status Register reports
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	 * link.  If so, then we want to get the current speed/duplex
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
	 * of the PHY.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	if (!link)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		return ret_val; /* No link detected */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	mac->get_link_status = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	 * Check if there was DownShift, must be checked
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	 * immediately after link-up
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	e1000e_check_downshift(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	 * If we are forcing speed/duplex, then we simply return since
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	 * we have already determined whether we have link or not.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
	if (!mac->autoneg) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		ret_val = -E1000_ERR_CONFIG;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	 * Auto-Neg is enabled.  Auto Speed Detection takes care
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	 * of MAC speed/duplex configuration.  So we only need to
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	 * configure Collision Distance in the MAC.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	e1000e_config_collision_dist(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	 * Configure Flow Control now that Auto-Neg has completed.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	 * First, we need to restore the desired flow control
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	 * settings because we may have had to re-autoneg with a
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	 * different link partner.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	ret_val = e1000e_config_fc_after_link_up(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		e_dbg("Error configuring flow control\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
 *  e1000e_check_for_fiber_link - Check for link (Fiber)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
 *  Checks for link up on the hardware.  If link is not up and we have
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
 *  a signal, then we need to force link up.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	u32 rxcw;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	u32 ctrl;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	u32 status;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	ctrl = er32(CTRL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	status = er32(STATUS);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	rxcw = er32(RXCW);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	 * If we don't have link (auto-negotiation failed or link partner
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	 * cannot auto-negotiate), the cable is plugged in (we have signal),
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	 * and our link partner is not trying to auto-negotiate with us (we
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	 * are receiving idles or data), we need to force link up. We also
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	 * need to give auto-negotiation time to complete, in case the cable
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	 * was just plugged in. The autoneg_failed flag does this.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	    (!(rxcw & E1000_RXCW_C))) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
		if (mac->autoneg_failed == 0) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
			mac->autoneg_failed = 1;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
			return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
		/* Disable auto-negotiation in the TXCW register */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
		/* Force link-up and also force full-duplex. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
		ctrl = er32(CTRL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
		ew32(CTRL, ctrl);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
		/* Configure Flow Control after forcing link up. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
		ret_val = e1000e_config_fc_after_link_up(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
		if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
			e_dbg("Error configuring flow control\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
		 * If we are forcing link and we are receiving /C/ ordered
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
		 * sets, re-enable auto-negotiation in the TXCW register
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		 * and disable forced link in the Device Control register
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		 * in an attempt to auto-negotiate with our link partner.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
		ew32(TXCW, mac->txcw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
		mac->serdes_has_link = true;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
 *  e1000e_check_for_serdes_link - Check for link (Serdes)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
 *  Checks for link up on the hardware.  If link is not up and we have
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
 *  a signal, then we need to force link up.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	u32 rxcw;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	u32 ctrl;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	u32 status;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	ctrl = er32(CTRL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	status = er32(STATUS);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	rxcw = er32(RXCW);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	 * If we don't have link (auto-negotiation failed or link partner
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	 * cannot auto-negotiate), and our link partner is not trying to
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	 * auto-negotiate with us (we are receiving idles or data),
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	 * we need to force link up. We also need to give auto-negotiation
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	 * time to complete.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		if (mac->autoneg_failed == 0) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
			mac->autoneg_failed = 1;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
			return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		/* Disable auto-negotiation in the TXCW register */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
		/* Force link-up and also force full-duplex. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
		ctrl = er32(CTRL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		ew32(CTRL, ctrl);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
		/* Configure Flow Control after forcing link up. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		ret_val = e1000e_config_fc_after_link_up(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
			e_dbg("Error configuring flow control\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
		 * If we are forcing link and we are receiving /C/ ordered
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
		 * sets, re-enable auto-negotiation in the TXCW register
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		 * and disable forced link in the Device Control register
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
		 * in an attempt to auto-negotiate with our link partner.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		ew32(TXCW, mac->txcw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
		mac->serdes_has_link = true;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		 * If we force link for non-auto-negotiation switch, check
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		 * link status based on MAC synchronization for internal
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		 * serdes media type.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
		/* SYNCH bit and IV bit are sticky. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
		udelay(10);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
		rxcw = er32(RXCW);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
		if (rxcw & E1000_RXCW_SYNCH) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
			if (!(rxcw & E1000_RXCW_IV)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
				mac->serdes_has_link = true;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
				e_dbg("SERDES: Link up - forced.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
			}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
		} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
			mac->serdes_has_link = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
			e_dbg("SERDES: Link down - force failed.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	if (E1000_TXCW_ANE & er32(TXCW)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		status = er32(STATUS);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
		if (status & E1000_STATUS_LU) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
			/* SYNCH bit and IV bit are sticky, so reread rxcw.  */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
			udelay(10);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
			rxcw = er32(RXCW);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
			if (rxcw & E1000_RXCW_SYNCH) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
				if (!(rxcw & E1000_RXCW_IV)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
					mac->serdes_has_link = true;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
					e_dbg("SERDES: Link up - autoneg "
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
					   "completed successfully.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
				} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
					mac->serdes_has_link = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
					e_dbg("SERDES: Link down - invalid"
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
					   "codewords detected in autoneg.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
				}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
			} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
				mac->serdes_has_link = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
				e_dbg("SERDES: Link down - no sync.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
			}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
		} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
			mac->serdes_has_link = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
			e_dbg("SERDES: Link down - autoneg failed\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
 *  e1000_set_default_fc_generic - Set flow control default values
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
 *  Read the EEPROM for the default values for flow control and store the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
 *  values.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	u16 nvm_data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	 * Read and store word 0x0F of the EEPROM. This word contains bits
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	 * that determine the hardware's default PAUSE (flow control) mode,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	 * a bit that determines whether the HW defaults to enabling or
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
	 * disabling auto-negotiation, and the direction of the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	 * SW defined pins. If there is no SW over-ride of the flow
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	 * control setting, then the variable hw->fc will
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	 * be initialized based on a value in the EEPROM.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
	if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
		e_dbg("NVM Read Error\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
		hw->fc.requested_mode = e1000_fc_none;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
		 NVM_WORD0F_ASM_DIR)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
		hw->fc.requested_mode = e1000_fc_tx_pause;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	else
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
		hw->fc.requested_mode = e1000_fc_full;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
 *  e1000e_setup_link - Setup flow control and link settings
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
 *  Determines which flow control settings to use, then configures flow
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
 *  control.  Calls the appropriate media-specific link configuration
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
 *  function.  Assuming the adapter has a valid link partner, a valid link
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
 *  should be established.  Assumes the hardware has previously been reset
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
 *  and the transmitter and receiver are not enabled.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
s32 e1000e_setup_link(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	 * In the case of the phy reset being blocked, we already have a link.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
	 * We do not need to set it up again.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	if (e1000_check_reset_block(hw))
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
		return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	 * If requested flow control is set to default, set flow control
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	 * based on the EEPROM flow control settings.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	if (hw->fc.requested_mode == e1000_fc_default) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
		ret_val = e1000_set_default_fc_generic(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	 * Save off the requested flow control mode for use later.  Depending
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	 * on the link partner's capabilities, we may or may not use this mode.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	hw->fc.current_mode = hw->fc.requested_mode;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	e_dbg("After fix-ups FlowControl is now = %x\n",
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
		hw->fc.current_mode);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	/* Call the necessary media_type subroutine to configure the link. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	ret_val = mac->ops.setup_physical_interface(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	 * Initialize the flow control address, type, and PAUSE timer
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	 * registers to their default values.  This is done even if flow
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	 * control is disabled, because it does not hurt anything to
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	 * initialize these registers.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	e_dbg("Initializing the Flow Control address, type and timer regs\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	ew32(FCT, FLOW_CONTROL_TYPE);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	ew32(FCTTV, hw->fc.pause_time);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	return e1000e_set_fc_watermarks(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
 *  e1000_commit_fc_settings_generic - Configure flow control
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
 *  Write the flow control settings to the Transmit Config Word Register (TXCW)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
 *  base on the flow control settings in e1000_mac_info.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	u32 txcw;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	 * Check for a software override of the flow control settings, and
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	 * setup the device accordingly.  If auto-negotiation is enabled, then
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	 * software will have to set the "PAUSE" bits to the correct value in
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	 * the Transmit Config Word Register (TXCW) and re-start auto-
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	 * negotiation.  However, if auto-negotiation is disabled, then
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	 * software will have to manually configure the two flow control enable
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
	 * bits in the CTRL register.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
	 * The possible values of the "fc" parameter are:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
	 *      0:  Flow control is completely disabled
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	 *      1:  Rx flow control is enabled (we can receive pause frames,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	 *          but not send pause frames).
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	 *      2:  Tx flow control is enabled (we can send pause frames but we
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	 *          do not support receiving pause frames).
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	switch (hw->fc.current_mode) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	case e1000_fc_none:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
		/* Flow control completely disabled by a software over-ride. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	case e1000_fc_rx_pause:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
		 * Rx Flow control is enabled and Tx Flow control is disabled
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
		 * by a software over-ride. Since there really isn't a way to
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
		 * advertise that we are capable of Rx Pause ONLY, we will
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
		 * advertise that we support both symmetric and asymmetric Rx
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
		 * PAUSE.  Later, we will disable the adapter's ability to send
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		 * PAUSE frames.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	case e1000_fc_tx_pause:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		 * Tx Flow control is enabled, and Rx Flow control is disabled,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
		 * by a software over-ride.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	case e1000_fc_full:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
		 * Flow control (both Rx and Tx) is enabled by a software
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
		 * over-ride.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	default:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
		e_dbg("Flow control param set incorrectly\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		return -E1000_ERR_CONFIG;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	ew32(TXCW, txcw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	mac->txcw = txcw;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
 *  e1000_poll_fiber_serdes_link_generic - Poll for link up
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
 *  Polls for link up by reading the status register, if link fails to come
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
 *  up with auto-negotiation, then the link is forced if a signal is detected.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	u32 i, status;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	 * If we have a signal (the cable is plugged in, or assumed true for
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	 * serdes media) then poll for a "Link-Up" indication in the Device
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	 * Status Register.  Time-out if a link isn't seen in 500 milliseconds
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	 * seconds (Auto-negotiation should complete in less than 500
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	 * milliseconds even if the other end is doing it in SW).
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
		usleep_range(10000, 20000);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
		status = er32(STATUS);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		if (status & E1000_STATUS_LU)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	if (i == FIBER_LINK_UP_LIMIT) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		e_dbg("Never got a valid link from auto-neg!!!\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
		mac->autoneg_failed = 1;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
		 * AutoNeg failed to achieve a link, so we'll call
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
		 * mac->check_for_link. This routine will force the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
		 * link up if we detect a signal. This will allow us to
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
		 * communicate with non-autonegotiating link partners.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		ret_val = mac->ops.check_for_link(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
			e_dbg("Error while checking for link\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
		mac->autoneg_failed = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		mac->autoneg_failed = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
		e_dbg("Valid Link Found\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
 *  e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
 *  Configures collision distance and flow control for fiber and serdes
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
 *  links.  Upon successful setup, poll for link.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	u32 ctrl;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	ctrl = er32(CTRL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	/* Take the link out of reset */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	ctrl &= ~E1000_CTRL_LRST;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	e1000e_config_collision_dist(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	ret_val = e1000_commit_fc_settings_generic(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	 * Since auto-negotiation is enabled, take the link out of reset (the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	 * link will be in reset, because we previously reset the chip). This
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	 * will restart auto-negotiation.  If auto-negotiation is successful
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	 * then the link-up status bit will be set and the flow control enable
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	 * bits (RFCE and TFCE) will be set according to their negotiated value.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	e_dbg("Auto-negotiation enabled\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	ew32(CTRL, ctrl);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	usleep_range(1000, 2000);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
	 * For these adapters, the SW definable pin 1 is set when the optics
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	 * detect a signal.  If we have a signal, then poll for a "Link-Up"
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
	 * indication.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	if (hw->phy.media_type == e1000_media_type_internal_serdes ||
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	    (er32(CTRL) & E1000_CTRL_SWDPIN1)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
		ret_val = e1000_poll_fiber_serdes_link_generic(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		e_dbg("No signal detected\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
 *  e1000e_config_collision_dist - Configure collision distance
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
 *  Configures the collision distance to the default value and is used
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
 *  during link setup. Currently no func pointer exists and all
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
 *  implementations are handled in the generic version of this function.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
void e1000e_config_collision_dist(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	u32 tctl;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	tctl = er32(TCTL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	tctl &= ~E1000_TCTL_COLD;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	ew32(TCTL, tctl);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
 *  e1000e_set_fc_watermarks - Set flow control high/low watermarks
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
 *  Sets the flow control high/low threshold (watermark) registers.  If
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
 *  flow control XON frame transmission is enabled, then set XON frame
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
 *  transmission as well.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	u32 fcrtl = 0, fcrth = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	 * Set the flow control receive threshold registers.  Normally,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	 * these registers will be set to a default threshold that may be
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	 * adjusted later by the driver's runtime code.  However, if the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	 * ability to transmit pause frames is not enabled, then these
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	 * registers will be set to 0.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	if (hw->fc.current_mode & e1000_fc_tx_pause) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
		 * We need to set up the Receive Threshold high and low water
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
		 * marks as well as (optionally) enabling the transmission of
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
		 * XON frames.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
		fcrtl = hw->fc.low_water;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		fcrtl |= E1000_FCRTL_XONE;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		fcrth = hw->fc.high_water;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	ew32(FCRTL, fcrtl);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
	ew32(FCRTH, fcrth);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
 *  e1000e_force_mac_fc - Force the MAC's flow control settings
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
 *  Force the MAC's flow control settings.  Sets the TFCE and RFCE bits in the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
 *  device control register to reflect the adapter settings.  TFCE and RFCE
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
 *  need to be explicitly set by software when a copper PHY is used because
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
 *  autonegotiation is managed by the PHY rather than the MAC.  Software must
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
 *  also configure these bits when link is forced on a fiber connection.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
s32 e1000e_force_mac_fc(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
	u32 ctrl;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	ctrl = er32(CTRL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	 * Because we didn't get link via the internal auto-negotiation
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	 * mechanism (we either forced link or we got link via PHY
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	 * auto-neg), we have to manually enable/disable transmit an
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
	 * receive flow control.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	 * The "Case" statement below enables/disable flow control
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	 * according to the "hw->fc.current_mode" parameter.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
	 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	 * The possible values of the "fc" parameter are:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	 *      0:  Flow control is completely disabled
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	 *      1:  Rx flow control is enabled (we can receive pause
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	 *          frames but not send pause frames).
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	 *      2:  Tx flow control is enabled (we can send pause frames
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	 *          frames but we do not receive pause frames).
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	 *      3:  Both Rx and Tx flow control (symmetric) is enabled.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	 *  other:  No other values should be possible at this point.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	switch (hw->fc.current_mode) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	case e1000_fc_none:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	case e1000_fc_rx_pause:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
		ctrl &= (~E1000_CTRL_TFCE);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		ctrl |= E1000_CTRL_RFCE;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	case e1000_fc_tx_pause:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
		ctrl &= (~E1000_CTRL_RFCE);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		ctrl |= E1000_CTRL_TFCE;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	case e1000_fc_full:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	default:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		e_dbg("Flow control param set incorrectly\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		return -E1000_ERR_CONFIG;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	ew32(CTRL, ctrl);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
 *  e1000e_config_fc_after_link_up - Configures flow control after link
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
 *  Checks the status of auto-negotiation after link up to ensure that the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
 *  speed and duplex were not forced.  If the link needed to be forced, then
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
 *  flow control needs to be forced also.  If auto-negotiation is enabled
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
 *  and did not fail, then we configure flow control based on our link
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
 *  partner.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	s32 ret_val = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	u16 speed, duplex;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	 * Check for the case where we have fiber media and auto-neg failed
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	 * so we had to force link.  In this case, we need to force the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	 * configuration of the MAC to match the "fc" parameter.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	if (mac->autoneg_failed) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		if (hw->phy.media_type == e1000_media_type_fiber ||
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		    hw->phy.media_type == e1000_media_type_internal_serdes)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
			ret_val = e1000e_force_mac_fc(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
	} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		if (hw->phy.media_type == e1000_media_type_copper)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
			ret_val = e1000e_force_mac_fc(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		e_dbg("Error forcing flow control settings\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	 * Check for the case where we have copper media and auto-neg is
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	 * enabled.  In this case, we need to check and see if Auto-Neg
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	 * has completed, and if so, how the PHY and link partner has
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	 * flow control configured.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
		 * Read the MII Status Register and check to see if AutoNeg
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
		 * has completed.  We read this twice because this reg has
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
		 * some "sticky" (latched) bits.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
		ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
		if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
		ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
		if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
		if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
			e_dbg("Copper PHY and Auto Neg "
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
				 "has not completed.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		 * The AutoNeg process has completed, so we now need to
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
		 * read both the Auto Negotiation Advertisement
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
		 * Register (Address 4) and the Auto_Negotiation Base
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		 * Page Ability Register (Address 5) to determine how
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		 * flow control was negotiated.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
		if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		ret_val =
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		    e1e_rphy(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
		if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		 * Two bits in the Auto Negotiation Advertisement Register
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		 * (Address 4) and two bits in the Auto Negotiation Base
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		 * Page Ability Register (Address 5) determine flow control
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		 * for both the PHY and the link partner.  The following
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		 * 1999, describes these PAUSE resolution bits and how flow
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		 * control is determined based upon these settings.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		 * NOTE:  DC = Don't Care
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		 *   LOCAL DEVICE  |   LINK PARTNER
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
		 *-------|---------|-------|---------|--------------------
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		 *   0   |    0    |  DC   |   DC    | e1000_fc_none
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
		 *   0   |    1    |   0   |   DC    | e1000_fc_none
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
		 *   0   |    1    |   1   |    0    | e1000_fc_none
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
		 *   1   |    0    |   0   |   DC    | e1000_fc_none
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		 *   1   |   DC    |   1   |   DC    | e1000_fc_full
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		 *   1   |    1    |   0   |    0    | e1000_fc_none
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
		 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		 * Are both PAUSE bits set to 1?  If so, this implies
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		 * Symmetric Flow Control is enabled at both ends.  The
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		 * ASM_DIR bits are irrelevant per the spec.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
		 * For Symmetric Flow Control:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		 *   LOCAL DEVICE  |   LINK PARTNER
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
		 *-------|---------|-------|---------|--------------------
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		 *   1   |   DC    |   1   |   DC    | E1000_fc_full
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
		 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
		if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
		    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
			/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
			 * Now we need to check if the user selected Rx ONLY
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
			 * of pause frames.  In this case, we had to advertise
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
			 * FULL flow control because we could not advertise Rx
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
			 * ONLY. Hence, we must now check to see if we need to
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
			 * turn OFF the TRANSMISSION of PAUSE frames.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
			 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
			if (hw->fc.requested_mode == e1000_fc_full) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
				hw->fc.current_mode = e1000_fc_full;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
				e_dbg("Flow Control = FULL.\r\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
			} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
				hw->fc.current_mode = e1000_fc_rx_pause;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
				e_dbg("Flow Control = "
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
				      "Rx PAUSE frames only.\r\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
			}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		 * For receiving PAUSE frames ONLY.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		 *   LOCAL DEVICE  |   LINK PARTNER
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		 *-------|---------|-------|---------|--------------------
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
		else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
			  (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
			  (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
			  (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
			hw->fc.current_mode = e1000_fc_tx_pause;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
			e_dbg("Flow Control = Tx PAUSE frames only.\r\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
		 * For transmitting PAUSE frames ONLY.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		 *   LOCAL DEVICE  |   LINK PARTNER
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		 *-------|---------|-------|---------|--------------------
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
		else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
			 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
			 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
			 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
			hw->fc.current_mode = e1000_fc_rx_pause;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
			e_dbg("Flow Control = Rx PAUSE frames only.\r\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
			/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
			 * Per the IEEE spec, at this point flow control
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
			 * should be disabled.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
			 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
			hw->fc.current_mode = e1000_fc_none;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
			e_dbg("Flow Control = NONE.\r\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		 * Now we need to do one last check...  If we auto-
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		 * negotiated to HALF DUPLEX, flow control should not be
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
		 * enabled per IEEE 802.3 spec.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
		ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
		if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
			e_dbg("Error getting link speed and duplex\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
		if (duplex == HALF_DUPLEX)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
			hw->fc.current_mode = e1000_fc_none;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
		 * Now we call a subroutine to actually force the MAC
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
		 * controller to use the correct flow control settings.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
		ret_val = e1000e_force_mac_fc(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
		if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
			e_dbg("Error forcing flow control settings\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
 *  e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
 *  @speed: stores the current speed
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
 *  @duplex: stores the current duplex
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 *  Read the status register for the current speed/duplex and store the current
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
 *  speed and duplex for copper connections.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *duplex)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	u32 status;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	status = er32(STATUS);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	if (status & E1000_STATUS_SPEED_1000)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
		*speed = SPEED_1000;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	else if (status & E1000_STATUS_SPEED_100)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
		*speed = SPEED_100;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	else
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
		*speed = SPEED_10;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	if (status & E1000_STATUS_FD)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		*duplex = FULL_DUPLEX;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	else
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
		*duplex = HALF_DUPLEX;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	e_dbg("%u Mbps, %s Duplex\n",
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	      *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	      *duplex == FULL_DUPLEX ? "Full" : "Half");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
 *  e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
 *  @speed: stores the current speed
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
 *  @duplex: stores the current duplex
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
 *  Sets the speed and duplex to gigabit full duplex (the only possible option)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
 *  for fiber/serdes links.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, u16 *duplex)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	*speed = SPEED_1000;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	*duplex = FULL_DUPLEX;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
 *  e1000e_get_hw_semaphore - Acquire hardware semaphore
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
 *  Acquire the HW semaphore to access the PHY or NVM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
s32 e1000e_get_hw_semaphore(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	u32 swsm;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
	s32 timeout = hw->nvm.word_size + 1;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	s32 i = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	/* Get the SW semaphore */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	while (i < timeout) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
		swsm = er32(SWSM);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
		if (!(swsm & E1000_SWSM_SMBI))
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
		udelay(50);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
		i++;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	if (i == timeout) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
		e_dbg("Driver can't access device - SMBI bit is set.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
		return -E1000_ERR_NVM;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	/* Get the FW semaphore. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
	for (i = 0; i < timeout; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
		swsm = er32(SWSM);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
		/* Semaphore acquired if bit latched */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
		if (er32(SWSM) & E1000_SWSM_SWESMBI)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
		udelay(50);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
	if (i == timeout) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
		/* Release semaphores */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
		e1000e_put_hw_semaphore(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
		e_dbg("Driver can't access the NVM\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
		return -E1000_ERR_NVM;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
 *  e1000e_put_hw_semaphore - Release hardware semaphore
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
 *  Release hardware semaphore used to access the PHY or NVM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
void e1000e_put_hw_semaphore(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	u32 swsm;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
	swsm = er32(SWSM);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
	swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	ew32(SWSM, swsm);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
 *  e1000e_get_auto_rd_done - Check for auto read completion
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
 *  Check EEPROM for Auto Read done bit.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
s32 e1000e_get_auto_rd_done(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	s32 i = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	while (i < AUTO_READ_DONE_TIMEOUT) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
		if (er32(EECD) & E1000_EECD_AUTO_RD)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		usleep_range(1000, 2000);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
		i++;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
	if (i == AUTO_READ_DONE_TIMEOUT) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
		e_dbg("Auto read by HW from NVM has not completed.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
		return -E1000_ERR_RESET;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
 *  e1000e_valid_led_default - Verify a valid default LED config
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
 *  @data: pointer to the NVM (EEPROM)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
 *  Read the EEPROM for the current default LED configuration.  If the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
 *  LED configuration is not valid, set to a valid LED configuration.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		e_dbg("NVM Read Error\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
		*data = ID_LED_DEFAULT;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
 *  e1000e_id_led_init -
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
s32 e1000e_id_led_init(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	const u32 ledctl_mask = 0x000000FF;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
	u16 data, i, temp;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
	const u16 led_mask = 0x0F;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	ret_val = hw->nvm.ops.valid_led_default(hw, &data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
	mac->ledctl_default = er32(LEDCTL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	mac->ledctl_mode1 = mac->ledctl_default;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	mac->ledctl_mode2 = mac->ledctl_default;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	for (i = 0; i < 4; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
		temp = (data >> (i << 2)) & led_mask;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
		switch (temp) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
		case ID_LED_ON1_DEF2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
		case ID_LED_ON1_ON2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
		case ID_LED_ON1_OFF2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
			mac->ledctl_mode1 |= ledctl_on << (i << 3);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
		case ID_LED_OFF1_DEF2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
		case ID_LED_OFF1_ON2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
		case ID_LED_OFF1_OFF2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
			mac->ledctl_mode1 |= ledctl_off << (i << 3);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
		default:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
			/* Do nothing */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		switch (temp) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
		case ID_LED_DEF1_ON2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
		case ID_LED_ON1_ON2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
		case ID_LED_OFF1_ON2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
			mac->ledctl_mode2 |= ledctl_on << (i << 3);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
		case ID_LED_DEF1_OFF2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
		case ID_LED_ON1_OFF2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
		case ID_LED_OFF1_OFF2:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
			mac->ledctl_mode2 |= ledctl_off << (i << 3);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
		default:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
			/* Do nothing */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
 *  e1000e_setup_led_generic - Configures SW controllable LED
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
 *  This prepares the SW controllable LED for use and saves the current state
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
 *  of the LED so it can be later restored.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
s32 e1000e_setup_led_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
	u32 ledctl;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
	if (hw->mac.ops.setup_led != e1000e_setup_led_generic)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
		return -E1000_ERR_CONFIG;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	if (hw->phy.media_type == e1000_media_type_fiber) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
		ledctl = er32(LEDCTL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
		hw->mac.ledctl_default = ledctl;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		/* Turn off LED0 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
		ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
		            E1000_LEDCTL_LED0_BLINK |
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		            E1000_LEDCTL_LED0_MODE_MASK);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
		ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
		           E1000_LEDCTL_LED0_MODE_SHIFT);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		ew32(LEDCTL, ledctl);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	} else if (hw->phy.media_type == e1000_media_type_copper) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
		ew32(LEDCTL, hw->mac.ledctl_mode1);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
 *  e1000e_cleanup_led_generic - Set LED config to default operation
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
 *  Remove the current LED configuration and set the LED configuration
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
 *  to the default value, saved from the EEPROM.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	ew32(LEDCTL, hw->mac.ledctl_default);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
 *  e1000e_blink_led_generic - Blink LED
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
 *  Blink the LEDs which are set to be on.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
s32 e1000e_blink_led_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	u32 ledctl_blink = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	u32 i;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	if (hw->phy.media_type == e1000_media_type_fiber) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		/* always blink LED0 for PCI-E fiber */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		ledctl_blink = E1000_LEDCTL_LED0_BLINK |
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		     (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		 * set the blink bit for each LED that's "on" (0x0E)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		 * in ledctl_mode2
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		ledctl_blink = hw->mac.ledctl_mode2;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		for (i = 0; i < 4; i++)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
			if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
			    E1000_LEDCTL_MODE_LED_ON)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
						 (i * 8));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
	ew32(LEDCTL, ledctl_blink);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
 *  e1000e_led_on_generic - Turn LED on
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
 *  Turn LED on.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
s32 e1000e_led_on_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	u32 ctrl;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	switch (hw->phy.media_type) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	case e1000_media_type_fiber:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
		ctrl = er32(CTRL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
		ctrl &= ~E1000_CTRL_SWDPIN0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
		ctrl |= E1000_CTRL_SWDPIO0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
		ew32(CTRL, ctrl);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
	case e1000_media_type_copper:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
		ew32(LEDCTL, hw->mac.ledctl_mode2);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	default:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
 *  e1000e_led_off_generic - Turn LED off
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
 *  Turn LED off.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
s32 e1000e_led_off_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	u32 ctrl;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	switch (hw->phy.media_type) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	case e1000_media_type_fiber:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		ctrl = er32(CTRL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
		ctrl |= E1000_CTRL_SWDPIN0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
		ctrl |= E1000_CTRL_SWDPIO0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		ew32(CTRL, ctrl);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	case e1000_media_type_copper:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		ew32(LEDCTL, hw->mac.ledctl_mode1);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
	default:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
 *  e1000e_set_pcie_no_snoop - Set PCI-express capabilities
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
 *  @no_snoop: bitmap of snoop events
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
 *  Set the PCI-express register to snoop for events enabled in 'no_snoop'.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	u32 gcr;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
	if (no_snoop) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		gcr = er32(GCR);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		gcr &= ~(PCIE_NO_SNOOP_ALL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		gcr |= no_snoop;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		ew32(GCR, gcr);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
 *  e1000e_disable_pcie_master - Disables PCI-express master access
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
 *  Returns 0 if successful, else returns -10
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
 *  (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
 *  the master requests to be disabled.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
 *  Disables PCI-Express master access and verifies there are no pending
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
 *  requests.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
s32 e1000e_disable_pcie_master(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
	u32 ctrl;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	s32 timeout = MASTER_DISABLE_TIMEOUT;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	ctrl = er32(CTRL);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	ew32(CTRL, ctrl);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	while (timeout) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		if (!(er32(STATUS) &
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
		      E1000_STATUS_GIO_MASTER_ENABLE))
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
		udelay(100);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
		timeout--;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	if (!timeout) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		e_dbg("Master requests are pending.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		return -E1000_ERR_MASTER_REQUESTS_PENDING;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
 *  e1000e_reset_adaptive - Reset Adaptive Interframe Spacing
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
 *  Reset the Adaptive Interframe Spacing throttle to default values.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
void e1000e_reset_adaptive(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	if (!mac->adaptive_ifs) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
		e_dbg("Not in Adaptive IFS mode!\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	mac->current_ifs_val = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
	mac->ifs_min_val = IFS_MIN;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	mac->ifs_max_val = IFS_MAX;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	mac->ifs_step_size = IFS_STEP;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	mac->ifs_ratio = IFS_RATIO;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	mac->in_ifs_mode = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	ew32(AIT, 0);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
out:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	return;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
 *  e1000e_update_adaptive - Update Adaptive Interframe Spacing
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
 *  Update the Adaptive Interframe Spacing Throttle value based on the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
 *  time between transmitted packets and time between collisions.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
void e1000e_update_adaptive(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	struct e1000_mac_info *mac = &hw->mac;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	if (!mac->adaptive_ifs) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
		e_dbg("Not in Adaptive IFS mode!\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
		if (mac->tx_packet_delta > MIN_NUM_XMITS) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
			mac->in_ifs_mode = true;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
			if (mac->current_ifs_val < mac->ifs_max_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
				if (!mac->current_ifs_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
					mac->current_ifs_val = mac->ifs_min_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
				else
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
					mac->current_ifs_val +=
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
						mac->ifs_step_size;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
				ew32(AIT, mac->current_ifs_val);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
			}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	} else {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		if (mac->in_ifs_mode &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
			mac->current_ifs_val = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
			mac->in_ifs_mode = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
			ew32(AIT, 0);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
out:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	return;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
 *  e1000_raise_eec_clk - Raise EEPROM clock
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
 *  @eecd: pointer to the EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
 *  Enable/Raise the EEPROM clock bit.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	*eecd = *eecd | E1000_EECD_SK;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	ew32(EECD, *eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
	udelay(hw->nvm.delay_usec);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
 *  e1000_lower_eec_clk - Lower EEPROM clock
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
 *  @eecd: pointer to the EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
 *  Clear/Lower the EEPROM clock bit.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	*eecd = *eecd & ~E1000_EECD_SK;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	ew32(EECD, *eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	udelay(hw->nvm.delay_usec);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
 *  e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
 *  @data: data to send to the EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
 *  @count: number of bits to shift out
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
 *  We need to shift 'count' bits out to the EEPROM.  So, the value in the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
 *  "data" parameter will be shifted out to the EEPROM one bit at a time.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
 *  In order to do this, "data" must be broken down into bits.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
	struct e1000_nvm_info *nvm = &hw->nvm;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	u32 eecd = er32(EECD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	u32 mask;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	mask = 0x01 << (count - 1);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
	if (nvm->type == e1000_nvm_eeprom_spi)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
		eecd |= E1000_EECD_DO;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
	do {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		eecd &= ~E1000_EECD_DI;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		if (data & mask)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
			eecd |= E1000_EECD_DI;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
		ew32(EECD, eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
		e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
		udelay(nvm->delay_usec);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		e1000_raise_eec_clk(hw, &eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
		e1000_lower_eec_clk(hw, &eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		mask >>= 1;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	} while (mask);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	eecd &= ~E1000_EECD_DI;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	ew32(EECD, eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
 *  e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
 *  @count: number of bits to shift in
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
 *  In order to read a register from the EEPROM, we need to shift 'count' bits
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
 *  in from the EEPROM.  Bits are "shifted in" by raising the clock input to
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
 *  the EEPROM (setting the SK bit), and then reading the value of the data out
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
 *  "DO" bit.  During this "shifting in" process the data in "DI" bit should
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
 *  always be clear.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
	u32 eecd;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
	u32 i;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	u16 data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
	eecd = er32(EECD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
	data = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
	for (i = 0; i < count; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
		data <<= 1;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
		e1000_raise_eec_clk(hw, &eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
		eecd = er32(EECD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
		eecd &= ~E1000_EECD_DI;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		if (eecd & E1000_EECD_DO)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
			data |= 1;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
		e1000_lower_eec_clk(hw, &eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	return data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
 *  e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
 *  @ee_reg: EEPROM flag for polling
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
 *  Polls the EEPROM status bit for either read or write completion based
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
 *  upon the value of 'ee_reg'.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	u32 attempts = 100000;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	u32 i, reg = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
	for (i = 0; i < attempts; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		if (ee_reg == E1000_NVM_POLL_READ)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
			reg = er32(EERD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
		else
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
			reg = er32(EEWR);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		if (reg & E1000_NVM_RW_REG_DONE)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
			return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
		udelay(5);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	return -E1000_ERR_NVM;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
 *  e1000e_acquire_nvm - Generic request for access to EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
 *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
 *  Return successful if access grant bit set, else clear the request for
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
 *  EEPROM access and return -E1000_ERR_NVM (-1).
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
s32 e1000e_acquire_nvm(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	u32 eecd = er32(EECD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
	s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
	ew32(EECD, eecd | E1000_EECD_REQ);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
	eecd = er32(EECD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	while (timeout) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
		if (eecd & E1000_EECD_GNT)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
		udelay(5);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
		eecd = er32(EECD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
		timeout--;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	if (!timeout) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
		eecd &= ~E1000_EECD_REQ;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
		ew32(EECD, eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
		e_dbg("Could not acquire NVM grant\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
		return -E1000_ERR_NVM;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
 *  e1000_standby_nvm - Return EEPROM to standby state
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
 *  Return the EEPROM to a standby state.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
static void e1000_standby_nvm(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	struct e1000_nvm_info *nvm = &hw->nvm;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	u32 eecd = er32(EECD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	if (nvm->type == e1000_nvm_eeprom_spi) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
		/* Toggle CS to flush commands */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
		eecd |= E1000_EECD_CS;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
		ew32(EECD, eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
		e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
		udelay(nvm->delay_usec);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
		eecd &= ~E1000_EECD_CS;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
		ew32(EECD, eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
		e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
		udelay(nvm->delay_usec);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
 *  e1000_stop_nvm - Terminate EEPROM command
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
 *  Terminates the current command by inverting the EEPROM's chip select pin.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
static void e1000_stop_nvm(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
	u32 eecd;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	eecd = er32(EECD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	if (hw->nvm.type == e1000_nvm_eeprom_spi) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		/* Pull CS high */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
		eecd |= E1000_EECD_CS;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
		e1000_lower_eec_clk(hw, &eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
 *  e1000e_release_nvm - Release exclusive access to EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
 *  Stop any current commands to the EEPROM and clear the EEPROM request bit.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
void e1000e_release_nvm(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	u32 eecd;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	e1000_stop_nvm(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	eecd = er32(EECD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
	eecd &= ~E1000_EECD_REQ;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
	ew32(EECD, eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
 *  e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
 *  Setups the EEPROM for reading and writing.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	struct e1000_nvm_info *nvm = &hw->nvm;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	u32 eecd = er32(EECD);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	u8 spi_stat_reg;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
	if (nvm->type == e1000_nvm_eeprom_spi) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
		u16 timeout = NVM_MAX_RETRY_SPI;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
		/* Clear SK and CS */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
		ew32(EECD, eecd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
		e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
		udelay(1);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
		 * Read "Status Register" repeatedly until the LSB is cleared.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
		 * The EEPROM will signal that the command has been completed
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
		 * by clearing bit 0 of the internal status register.  If it's
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
		 * not cleared within 'timeout', then error out.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
		while (timeout) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
			e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
						 hw->nvm.opcode_bits);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
			spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
			if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
				break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
			udelay(5);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
			e1000_standby_nvm(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
			timeout--;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
		if (!timeout) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
			e_dbg("SPI NVM Status error\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
			return -E1000_ERR_NVM;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
 *  e1000e_read_nvm_eerd - Reads EEPROM using EERD register
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
 *  @offset: offset of word in the EEPROM to read
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
 *  @words: number of words to read
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
 *  @data: word read from the EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
 *  Reads a 16 bit word from the EEPROM using the EERD register.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
	struct e1000_nvm_info *nvm = &hw->nvm;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	u32 i, eerd = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	s32 ret_val = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	 * A check for invalid values:  offset too large, too many words,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	 * too many words for the offset, and not enough words.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
	    (words == 0)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		e_dbg("nvm parameter(s) out of bounds\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
		return -E1000_ERR_NVM;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
	for (i = 0; i < words; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
		eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
		       E1000_NVM_RW_REG_START;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
		ew32(EERD, eerd);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
		ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
		if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
		data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
	return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
 *  e1000e_write_nvm_spi - Write to EEPROM using SPI
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
 *  @offset: offset within the EEPROM to be written to
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
 *  @words: number of words to write
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
 *  @data: 16 bit word(s) to be written to the EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
 *  Writes data to EEPROM at offset using SPI interface.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
 *  If e1000e_update_nvm_checksum is not called after this function , the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
 *  EEPROM will most likely contain an invalid checksum.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	struct e1000_nvm_info *nvm = &hw->nvm;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	u16 widx = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	 * A check for invalid values:  offset too large, too many words,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	 * and not enough words.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
	    (words == 0)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
		e_dbg("nvm parameter(s) out of bounds\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
		return -E1000_ERR_NVM;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
	ret_val = nvm->ops.acquire(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	while (widx < words) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
		u8 write_opcode = NVM_WRITE_OPCODE_SPI;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
		ret_val = e1000_ready_nvm_eeprom(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
		if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
			nvm->ops.release(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
		e1000_standby_nvm(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
		/* Send the WRITE ENABLE command (8 bit opcode) */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
		e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
					 nvm->opcode_bits);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
		e1000_standby_nvm(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
		/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
		 * Some SPI eeproms use the 8th address bit embedded in the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
		 * opcode
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
		 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
		if ((nvm->address_bits == 8) && (offset >= 128))
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
			write_opcode |= NVM_A8_OPCODE_SPI;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
		/* Send the Write command (8-bit opcode + addr) */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
		e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
		e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
					 nvm->address_bits);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
		/* Loop to allow for up to whole page write of eeprom */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
		while (widx < words) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
			u16 word_out = data[widx];
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
			word_out = (word_out >> 8) | (word_out << 8);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
			e1000_shift_out_eec_bits(hw, word_out, 16);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
			widx++;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
			if ((((offset + widx) * 2) % nvm->page_size) == 0) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
				e1000_standby_nvm(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
				break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
			}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	usleep_range(10000, 20000);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	nvm->ops.release(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
 *  e1000_read_pba_string_generic - Read device part number
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
 *  @pba_num: pointer to device part number
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
 *  @pba_num_size: size of part number buffer
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
 *  Reads the product board assembly (PBA) number from the EEPROM and stores
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
 *  the value in pba_num.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
				  u32 pba_num_size)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	u16 nvm_data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	u16 pba_ptr;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	u16 offset;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	u16 length;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
	if (pba_num == NULL) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
		e_dbg("PBA string buffer was null\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
		ret_val = E1000_ERR_INVALID_ARGUMENT;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
		e_dbg("NVM Read Error\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
	if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
		e_dbg("NVM Read Error\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	 * if nvm_data is not ptr guard the PBA must be in legacy format which
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
	 * means pba_ptr is actually our second data word for the PBA number
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
	 * and we can decode it into an ascii string
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	if (nvm_data != NVM_PBA_PTR_GUARD) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
		e_dbg("NVM PBA number is not stored as string\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
		/* we will need 11 characters to store the PBA */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
		if (pba_num_size < 11) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
			e_dbg("PBA string buffer too small\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
			return E1000_ERR_NO_SPACE;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
		/* extract hex string from data and pba_ptr */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
		pba_num[0] = (nvm_data >> 12) & 0xF;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
		pba_num[1] = (nvm_data >> 8) & 0xF;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
		pba_num[2] = (nvm_data >> 4) & 0xF;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
		pba_num[3] = nvm_data & 0xF;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
		pba_num[4] = (pba_ptr >> 12) & 0xF;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
		pba_num[5] = (pba_ptr >> 8) & 0xF;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
		pba_num[6] = '-';
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
		pba_num[7] = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
		pba_num[8] = (pba_ptr >> 4) & 0xF;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
		pba_num[9] = pba_ptr & 0xF;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
		/* put a null character on the end of our string */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
		pba_num[10] = '\0';
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
		/* switch all the data but the '-' to hex char */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
		for (offset = 0; offset < 10; offset++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
			if (pba_num[offset] < 0xA)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
				pba_num[offset] += '0';
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
			else if (pba_num[offset] < 0x10)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
				pba_num[offset] += 'A' - 0xA;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
		e_dbg("NVM Read Error\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	if (length == 0xFFFF || length == 0) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
		e_dbg("NVM PBA number section invalid length\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
		ret_val = E1000_ERR_NVM_PBA_SECTION;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
	/* check if pba_num buffer is big enough */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	if (pba_num_size < (((u32)length * 2) - 1)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
		e_dbg("PBA string buffer too small\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
		ret_val = E1000_ERR_NO_SPACE;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	/* trim pba length from start of string */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	pba_ptr++;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	length--;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
	for (offset = 0; offset < length; offset++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
		ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
		if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
			e_dbg("NVM Read Error\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
			goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
		pba_num[offset * 2] = (u8)(nvm_data >> 8);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
		pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	pba_num[offset * 2] = '\0';
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
out:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
 *  e1000_read_mac_addr_generic - Read device MAC address
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
 *  Reads the device MAC address from the EEPROM and stores the value.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
 *  Since devices with two ports use the same EEPROM, we increment the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
 *  last bit in the MAC address for the second port.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	u32 rar_high;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	u32 rar_low;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	u16 i;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	rar_high = er32(RAH(0));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	rar_low = er32(RAL(0));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
		hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
	for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
		hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
	for (i = 0; i < ETH_ALEN; i++)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
		hw->mac.addr[i] = hw->mac.perm_addr[i];
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
 *  e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
 *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
 *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	u16 checksum = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	u16 i, nvm_data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
		ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
		if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
			e_dbg("NVM Read Error\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
		checksum += nvm_data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
	if (checksum != (u16) NVM_SUM) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
		e_dbg("NVM Checksum Invalid\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
		return -E1000_ERR_NVM;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
 *  e1000e_update_nvm_checksum_generic - Update EEPROM checksum
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
 *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
 *  up to the checksum.  Then calculates the EEPROM checksum and writes the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
 *  value to the EEPROM.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	u16 checksum = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	u16 i, nvm_data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	for (i = 0; i < NVM_CHECKSUM_REG; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
		ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
		if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
			e_dbg("NVM Read Error while updating checksum.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
			return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
		checksum += nvm_data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
	checksum = (u16) NVM_SUM - checksum;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		e_dbg("NVM Write Error while updating checksum.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
 *  e1000e_reload_nvm - Reloads EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
 *  Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
 *  extended control register.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
void e1000e_reload_nvm(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
	u32 ctrl_ext;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
	udelay(10);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	ctrl_ext = er32(CTRL_EXT);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
	ctrl_ext |= E1000_CTRL_EXT_EE_RST;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	ew32(CTRL_EXT, ctrl_ext);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
	e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
 *  e1000_calculate_checksum - Calculate checksum for buffer
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
 *  @buffer: pointer to EEPROM
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
 *  @length: size of EEPROM to calculate a checksum for
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
 *  Calculates the checksum for some buffer on a specified length.  The
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
 *  checksum calculated is returned.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
	u32 i;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
	u8  sum = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	if (!buffer)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
		return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
	for (i = 0; i < length; i++)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
		sum += buffer[i];
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	return (u8) (0 - sum);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
 *  e1000_mng_enable_host_if - Checks host interface is enabled
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
 *  Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
 *  This function checks whether the HOST IF is enabled for command operation
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
 *  and also checks whether the previous command is completed.  It busy waits
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
 *  in case of previous command is not completed.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
	u32 hicr;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	u8 i;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	if (!(hw->mac.arc_subsystem_valid)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
		e_dbg("ARC subsystem not valid.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		return -E1000_ERR_HOST_INTERFACE_COMMAND;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	/* Check that the host interface is enabled. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	hicr = er32(HICR);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
	if ((hicr & E1000_HICR_EN) == 0) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
		e_dbg("E1000_HOST_EN bit disabled.\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
		return -E1000_ERR_HOST_INTERFACE_COMMAND;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
	/* check the previous command is completed */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
	for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
		hicr = er32(HICR);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
		if (!(hicr & E1000_HICR_C))
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
			break;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
		mdelay(1);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
		e_dbg("Previous command timeout failed .\n");
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
		return -E1000_ERR_HOST_INTERFACE_COMMAND;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
 *  e1000e_check_mng_mode_generic - check management mode
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
 *  Reads the firmware semaphore register and returns true (>0) if
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
 *  manageability is enabled, else false (0).
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
bool e1000e_check_mng_mode_generic(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	u32 fwsm = er32(FWSM);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	return (fwsm & E1000_FWSM_MODE_MASK) ==
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
		(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
 *  e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
 *  Enables packet filtering on transmit packets if manageability is enabled
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
 *  and host interface is enabled.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
	struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	u32 *buffer = (u32 *)&hw->mng_cookie;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
	u32 offset;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	s32 ret_val, hdr_csum, csum;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	u8 i, len;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	hw->mac.tx_pkt_filtering = true;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
	/* No manageability, no filtering */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
	if (!e1000e_check_mng_mode(hw)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
		hw->mac.tx_pkt_filtering = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
	 * If we can't read from the host interface for whatever
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
	 * reason, disable filtering.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
	ret_val = e1000_mng_enable_host_if(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
	if (ret_val) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
		hw->mac.tx_pkt_filtering = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	/* Read in the header.  Length and offset are in dwords. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
	len    = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
	offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	for (i = 0; i < len; i++)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
		*(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset + i);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
	hdr_csum = hdr->checksum;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	hdr->checksum = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
	csum = e1000_calculate_checksum((u8 *)hdr,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
					E1000_MNG_DHCP_COOKIE_LENGTH);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
	 * If either the checksums or signature don't match, then
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	 * the cookie area isn't considered valid, in which case we
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
	 * take the safe route of assuming Tx filtering is enabled.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
	if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
		hw->mac.tx_pkt_filtering = true;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
	/* Cookie area is valid, make the final check for filtering. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		hw->mac.tx_pkt_filtering = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
out:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	return hw->mac.tx_pkt_filtering;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
 *  e1000_mng_write_cmd_header - Writes manageability command header
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
 *  @hdr: pointer to the host interface command header
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
 *  Writes the command header after does the checksum calculation.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
				  struct e1000_host_mng_command_header *hdr)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	u16 i, length = sizeof(struct e1000_host_mng_command_header);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	/* Write the whole command header structure with new checksum. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
	length >>= 2;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	/* Write the relevant command block into the ram area. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	for (i = 0; i < length; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
					    *((u32 *) hdr + i));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
		e1e_flush();
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
 *  e1000_mng_host_if_write - Write to the manageability host interface
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
 *  @buffer: pointer to the host interface buffer
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
 *  @length: size of the buffer
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
 *  @offset: location in the buffer to write to
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
 *  @sum: sum of the data (not checksum)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
 *  This function writes the buffer content at the offset given on the host if.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
 *  It also does alignment considerations to do the writes in most efficient
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
 *  way.  Also fills up the sum of the buffer in *buffer parameter.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
				   u16 length, u16 offset, u8 *sum)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
	u8 *tmp;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	u8 *bufptr = buffer;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
	u32 data = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	u16 remaining, i, j, prev_bytes;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
	/* sum = only sum of the data and it is not checksum */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
	if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
		return -E1000_ERR_PARAM;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	tmp = (u8 *)&data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	prev_bytes = offset & 0x3;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
	offset >>= 2;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
	if (prev_bytes) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
		data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
		for (j = prev_bytes; j < sizeof(u32); j++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
			*(tmp + j) = *bufptr++;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
			*sum += *(tmp + j);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
		length -= j - prev_bytes;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
		offset++;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
	remaining = length & 0x3;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
	length -= remaining;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
	/* Calculate length in DWORDs */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
	length >>= 2;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
	/*
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	 * The device driver writes the relevant command block into the
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	 * ram area.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
	 */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
	for (i = 0; i < length; i++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
		for (j = 0; j < sizeof(u32); j++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
			*(tmp + j) = *bufptr++;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
			*sum += *(tmp + j);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	if (remaining) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
		for (j = 0; j < sizeof(u32); j++) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
			if (j < remaining)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
				*(tmp + j) = *bufptr++;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
			else
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
				*(tmp + j) = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
			*sum += *(tmp + j);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
 *  e1000e_mng_write_dhcp_info - Writes DHCP info to host interface
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
 *  @buffer: pointer to the host interface
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
 *  @length: size of the buffer
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
 *  Writes the DHCP information to the host interface.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
	struct e1000_host_mng_command_header hdr;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
	s32 ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
	u32 hicr;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
	hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	hdr.command_length = length;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	hdr.reserved1 = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
	hdr.reserved2 = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	hdr.checksum = 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	/* Enable the host interface */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
	ret_val = e1000_mng_enable_host_if(hw);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	/* Populate the host interface with the contents of "buffer". */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
	ret_val = e1000_mng_host_if_write(hw, buffer, length,
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
					  sizeof(hdr), &(hdr.checksum));
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	/* Write the manageability command header */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	ret_val = e1000_mng_write_cmd_header(hw, &hdr);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	if (ret_val)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
		return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	/* Tell the ARC a new command is pending. */
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
	hicr = er32(HICR);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	ew32(HICR, hicr | E1000_HICR_C);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
	return 0;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
/**
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
 *  e1000e_enable_mng_pass_thru - Check if management passthrough is needed
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
 *  @hw: pointer to the HW structure
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
 *
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
 *  Verifies the hardware needs to leave interface enabled so that frames can
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
 *  be directed to and from the management interface.
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
 **/
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
{
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	u32 manc;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	u32 fwsm, factps;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	bool ret_val = false;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	manc = er32(MANC);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	if (!(manc & E1000_MANC_RCV_TCO_EN))
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
		goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	if (hw->mac.has_fwsm) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
		fwsm = er32(FWSM);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
		factps = er32(FACTPS);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
		if (!(factps & E1000_FACTPS_MNGCG) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
		    ((fwsm & E1000_FWSM_MODE_MASK) ==
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
		     (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
			ret_val = true;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
			goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	} else if ((hw->mac.type == e1000_82574) ||
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
		   (hw->mac.type == e1000_82583)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
		u16 data;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
		factps = er32(FACTPS);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
		if (!(factps & E1000_FACTPS_MNGCG) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
		    ((data & E1000_NVM_INIT_CTRL2_MNGM) ==
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
		     (e1000_mng_mode_pt << 13))) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
			ret_val = true;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
			goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
		}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	} else if ((manc & E1000_MANC_SMBUS_EN) &&
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
		    !(manc & E1000_MANC_ASF_EN)) {
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
			ret_val = true;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
			goto out;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	}
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
out:
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	return ret_val;
fee219bb31a9 Added e1000e driver for kernel 3.2, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
}