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