devices/e1000e/lib-2.6.33-ethercat.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2218 2eb46694f484
permissions -rw-r--r--
devices/ccat: revert "limit rx processing to one frame per poll"

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2218
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2009 Intel Corporation.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
2eb46694f484 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
2eb46694f484 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,
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
2eb46694f484 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
2eb46694f484 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.,
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
2eb46694f484 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>
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000-2.6.33-ethercat.h"
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
enum e1000_mng_mode {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
	e1000_mng_mode_none = 0,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
	e1000_mng_mode_asf,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
	e1000_mng_mode_pt,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
	e1000_mng_mode_ipmi,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
	e1000_mng_mode_host_if_only
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
};
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#define E1000_FACTPS_MNGCG		0x20000000
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
/* Intel(R) Active Management Technology signature */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#define E1000_IAMT_SIGNATURE		0x544D4149
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
 *
2eb46694f484 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
2eb46694f484 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:
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	struct e1000_bus_info *bus = &hw->bus;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	struct e1000_adapter *adapter = hw->adapter;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	u32 status;
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	if (!cap_offset) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
		bus->width = e1000_bus_width_unknown;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
		pci_read_config_word(adapter->pdev,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
				     cap_offset + PCIE_LINK_STATUS,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
				     &pcie_link_status);
2eb46694f484 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 &
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
						     PCIE_LINK_WIDTH_MASK) >>
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
						    PCIE_LINK_WIDTH_SHIFT);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
			     &pci_header_type);
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
		status = er32(STATUS);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
		bus->func = (status & E1000_STATUS_FUNC_MASK)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
			    >> E1000_STATUS_FUNC_SHIFT;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
		bus->func = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
 *  setting all the values to 0.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	u32 offset;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
2eb46694f484 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++) {
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
		e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
 *  @offset: register offset in VLAN filter table
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
 *  the VLAN filter table.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
{
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
 *  @rar_count: receive address registers
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
 *  address registers to 0.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	u32 i;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
	u8 mac_addr[ETH_ALEN] = {0};
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	/* Setup the receive address */
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
2eb46694f484 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 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
	for (i = 1; i < rar_count; i++)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
		e1000e_rar_set(hw, mac_addr, i);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
 *  e1000e_rar_set - Set receive address register
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
 *  @addr: pointer to the receive address
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
 *  @index: receive address array register
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
 *  in by addr.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
	u32 rar_low, rar_high;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
	rar_low = ((u32) addr[0] |
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
		   ((u32) addr[1] << 8) |
2eb46694f484 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));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
2eb46694f484 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));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
2eb46694f484 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 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
	if (rar_low || rar_high)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
		rar_high |= E1000_RAH_AV;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
	/*
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
	 * The flushes avoid this.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
	ew32(RAL(index), rar_low);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
	e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
	ew32(RAH(index), rar_high);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
	e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
 *  @mc_addr: pointer to a multicast address
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
 *  e1000_mta_set_generic()
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	u32 hash_value, hash_mask;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
	u8 bit_shift = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	/* Register count multiplied by bits per register */
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	/*
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	while (hash_mask >> bit_shift != 0xFF)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
		bit_shift++;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	/*
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 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.
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
	 * 8-bit shifting total.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
	 *
2eb46694f484 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
2eb46694f484 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),
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
	 * values resulting from each mc_filter_type...
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
	 * [0] [1] [2] [3] [4] [5]
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	 * 01  AA  00  12  34  56
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
	 * LSB		 MSB
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
	switch (hw->mac.mc_filter_type) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	default:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	case 0:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	case 1:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
		bit_shift += 1;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	case 2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
		bit_shift += 2;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	case 3:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
		bit_shift += 4;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
2eb46694f484 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)) |
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
				  (((u16) mc_addr[5]) << bit_shift)));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	return hash_value;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
 *  @hw: pointer to the HW structure
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
 *
2eb46694f484 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.
2eb46694f484 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.
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
 *  unless there are workarounds that change this.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
 **/
2eb46694f484 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,
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
					u32 rar_used_count, u32 rar_count)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	u32 i;
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	if (!mcarray) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
		return;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	 * array, clear the filters.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	 */
2eb46694f484 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++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
		if (mc_addr_count) {
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
			mc_addr_count--;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
			mc_addr_list += ETH_ALEN;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
		} else {
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
			e1e_flush();
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
			e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
2eb46694f484 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. */
2eb46694f484 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--) {
2eb46694f484 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;
2eb46694f484 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);
2eb46694f484 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);
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
		hash_bit = hash_value & 0x1F;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
		mta = (1 << hash_bit);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
		mcarray[hash_reg] |= mta;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
		mc_addr_list += ETH_ALEN;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	/* write the hash table completely */
2eb46694f484 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++)
2eb46694f484 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]);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	kfree(mcarray);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
 *
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	er32(CRCERRS);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	er32(SYMERRS);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	er32(MPC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	er32(SCC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	er32(ECOL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	er32(MCC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	er32(LATECOL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
	er32(COLC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	er32(DC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	er32(SEC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	er32(RLEC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	er32(XONRXC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	er32(XONTXC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
	er32(XOFFRXC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	er32(XOFFTXC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	er32(FCRUC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	er32(GPRC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	er32(BPRC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	er32(MPRC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	er32(GPTC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	er32(GORCL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	er32(GORCH);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	er32(GOTCL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	er32(GOTCH);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
	er32(RNBC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	er32(RUC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
	er32(RFC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
	er32(ROC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	er32(RJC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
	er32(TORL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	er32(TORH);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
	er32(TOTL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	er32(TOTH);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
	er32(TPR);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	er32(TPT);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
	er32(MPTC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
	er32(BPTC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
/**
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	struct e1000_mac_info *mac = &hw->mac;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	bool link;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	 * Change or Rx Sequence Error interrupt.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
	if (!mac->get_link_status)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
		return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	 * of the PHY.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	if (!link)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		return ret_val; /* No link detected */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	mac->get_link_status = false;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	/*
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	 * immediately after link-up
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	e1000e_check_downshift(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
	/*
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	if (!mac->autoneg) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
		ret_val = -E1000_ERR_CONFIG;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	 * configure Collision Distance in the MAC.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	e1000e_config_collision_dist(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	/*
2eb46694f484 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.
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
	 * different link partner.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
		e_dbg("Error configuring flow control\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
/**
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	struct e1000_mac_info *mac = &hw->mac;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	u32 rxcw;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	u32 ctrl;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	u32 status;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	ctrl = er32(CTRL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	status = er32(STATUS);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	rxcw = er32(RXCW);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	/*
2eb46694f484 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
2eb46694f484 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),
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
2eb46694f484 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)) &&
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	    (!(rxcw & E1000_RXCW_C))) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		if (mac->autoneg_failed == 0) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
			mac->autoneg_failed = 1;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
			return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
		}
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
		/* Disable auto-negotiation in the TXCW register */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
2eb46694f484 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. */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		ctrl = er32(CTRL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		ew32(CTRL, ctrl);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		/* Configure Flow Control after forcing link up. */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
			e_dbg("Error configuring flow control\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
		}
2eb46694f484 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)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
		/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
		 */
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		ew32(TXCW, mac->txcw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		mac->serdes_has_link = true;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
/**
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	struct e1000_mac_info *mac = &hw->mac;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	u32 rxcw;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
	u32 ctrl;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
	u32 status;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	ctrl = er32(CTRL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	status = er32(STATUS);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	rxcw = er32(RXCW);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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),
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	 * time to complete.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
2eb46694f484 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))) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
		if (mac->autoneg_failed == 0) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
			mac->autoneg_failed = 1;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
			return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
		}
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
		/* Disable auto-negotiation in the TXCW register */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
2eb46694f484 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. */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
		ctrl = er32(CTRL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
		ew32(CTRL, ctrl);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
		/* Configure Flow Control after forcing link up. */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
		if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
			e_dbg("Error configuring flow control\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
		}
2eb46694f484 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)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
		/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
		 */
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
		ew32(TXCW, mac->txcw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
		mac->serdes_has_link = true;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
		/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
		 * serdes media type.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
		 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
		/* SYNCH bit and IV bit are sticky. */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
		udelay(10);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
		rxcw = er32(RXCW);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
		if (rxcw & E1000_RXCW_SYNCH) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
			if (!(rxcw & E1000_RXCW_IV)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
				mac->serdes_has_link = true;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
				e_dbg("SERDES: Link up - forced.\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
			}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
			mac->serdes_has_link = false;
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	if (E1000_TXCW_ANE & er32(TXCW)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
		status = er32(STATUS);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
		if (status & E1000_STATUS_LU) {
2eb46694f484 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.  */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
			udelay(10);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
			rxcw = er32(RXCW);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
			if (rxcw & E1000_RXCW_SYNCH) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
				if (!(rxcw & E1000_RXCW_IV)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
					mac->serdes_has_link = true;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
					e_dbg("SERDES: Link up - autoneg "
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
					   "completed sucessfully.\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
				} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
					mac->serdes_has_link = false;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
					e_dbg("SERDES: Link down - invalid"
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
					   "codewords detected in autoneg.\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
				}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
			} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
				mac->serdes_has_link = false;
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
			}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
			mac->serdes_has_link = false;
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
 *  values.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	u16 nvm_data;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	/*
2eb46694f484 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
2eb46694f484 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,
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		e_dbg("NVM Read Error\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
		hw->fc.requested_mode = e1000_fc_none;
2eb46694f484 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) ==
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		 NVM_WORD0F_ASM_DIR)
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	else
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
		hw->fc.requested_mode = e1000_fc_full;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
	struct e1000_mac_info *mac = &hw->mac;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	/*
2eb46694f484 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.
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	if (e1000_check_reset_block(hw))
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	/*
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	 * based on the EEPROM flow control settings.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	 */
2eb46694f484 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) {
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	/*
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	 */
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
2eb46694f484 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",
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		hw->fc.current_mode);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
2eb46694f484 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. */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	 * initialize these registers.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	 */
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
	ew32(FCT, FLOW_CONTROL_TYPE);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	ew32(FCTTV, hw->fc.pause_time);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	return e1000e_set_fc_watermarks(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
 *
2eb46694f484 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)
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	struct e1000_mac_info *mac = &hw->mac;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	u32 txcw;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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-
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	 * bits in the CTRL register.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	 *
2eb46694f484 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:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	 *      0:  Flow control is completely disabled
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	 *	  but not send pause frames).
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	 *	  do not support receiving pause frames).
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
	switch (hw->fc.current_mode) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	case e1000_fc_none:
2eb46694f484 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. */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	case e1000_fc_rx_pause:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
		/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
		 * PAUSE frames.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
		 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	case e1000_fc_tx_pause:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
		/*
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
		 * by a software over-ride.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
		 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	case e1000_fc_full:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
		/*
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		 * over-ride.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	default:
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
		return -E1000_ERR_CONFIG;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	ew32(TXCW, txcw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	mac->txcw = txcw;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	struct e1000_mac_info *mac = &hw->mac;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	u32 i, status;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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).
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	 */
2eb46694f484 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++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
		msleep(10);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
		status = er32(STATUS);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
		if (status & E1000_STATUS_LU)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	if (i == FIBER_LINK_UP_LIMIT) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
		mac->autoneg_failed = 1;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
		/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
		 * communicate with non-autonegotiating link partners.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
		if (ret_val) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		mac->autoneg_failed = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
		mac->autoneg_failed = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
		e_dbg("Valid Link Found\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
 *  links.  Upon successful setup, poll for link.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	u32 ctrl;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	ctrl = er32(CTRL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	/* Take the link out of reset */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	ctrl &= ~E1000_CTRL_LRST;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	e1000e_config_collision_dist(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	e_dbg("Auto-negotiation enabled\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	ew32(CTRL, ctrl);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	msleep(1);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	/*
2eb46694f484 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
2eb46694f484 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"
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	 * indication.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	 */
2eb46694f484 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 ||
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	    (er32(CTRL) & E1000_CTRL_SWDPIN1)) {
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		e_dbg("No signal detected\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
 *  e1000e_config_collision_dist - Configure collision distance
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	u32 tctl;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	tctl = er32(TCTL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	tctl &= ~E1000_TCTL_COLD;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	ew32(TCTL, tctl);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
 *  transmission as well.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	u32 fcrtl = 0, fcrth = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	/*
2eb46694f484 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,
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	 * registers will be set to 0.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	 */
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
		/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
		 * XON frames.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
		 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
		fcrtl = hw->fc.low_water;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
		fcrtl |= E1000_FCRTL_XONE;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
		fcrth = hw->fc.high_water;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	ew32(FCRTL, fcrtl);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	ew32(FCRTH, fcrth);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	u32 ctrl;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	ctrl = er32(CTRL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	 * receive flow control.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	 *
2eb46694f484 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:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	 *      0:  Flow control is completely disabled
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	 *	  frames but not send pause frames).
2eb46694f484 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
2eb46694f484 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).
2eb46694f484 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.
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	switch (hw->fc.current_mode) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	case e1000_fc_none:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	case e1000_fc_rx_pause:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
		ctrl &= (~E1000_CTRL_TFCE);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		ctrl |= E1000_CTRL_RFCE;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	case e1000_fc_tx_pause:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
		ctrl &= (~E1000_CTRL_RFCE);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
		ctrl |= E1000_CTRL_TFCE;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	case e1000_fc_full:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	default:
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		return -E1000_ERR_CONFIG;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	ew32(CTRL, ctrl);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
 *  partner.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	struct e1000_mac_info *mac = &hw->mac;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	s32 ret_val = 0;
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	u16 speed, duplex;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	if (mac->autoneg_failed) {
2eb46694f484 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 ||
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
			ret_val = e1000e_force_mac_fc(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	} else {
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
			ret_val = e1000e_force_mac_fc(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	if (ret_val) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	 * flow control configured.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	 */
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
		/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		 * some "sticky" (latched) bits.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
			return ret_val;
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
2eb46694f484 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)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
			e_dbg("Copper PHY and Auto Neg "
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
				 "has not completed.\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		/*
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		 * read both the Auto Negotiation Advertisement
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		 * flow control was negotiated.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
		 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
			return ret_val;
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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,
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
		 * control is determined based upon these settings.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
		 * NOTE:  DC = Don't Care
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
		 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
		 *   LOCAL DEVICE  |   LINK PARTNER
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
		 *-------|---------|-------|---------|--------------------
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
		 *   0   |    0    |  DC   |   DC    | e1000_fc_none
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
		 *   0   |    1    |   0   |   DC    | e1000_fc_none
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		 *   0   |    1    |   1   |    0    | e1000_fc_none
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
		 *   1   |    0    |   0   |   DC    | e1000_fc_none
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		 *   1   |   DC    |   1   |   DC    | e1000_fc_full
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		 *   1   |    1    |   0   |    0    | e1000_fc_none
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
		 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		 * For Symmetric Flow Control:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		 *   LOCAL DEVICE  |   LINK PARTNER
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		 *-------|---------|-------|---------|--------------------
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
		 *   1   |   DC    |   1   |   DC    | E1000_fc_full
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
		 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
		 */
2eb46694f484 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) &&
2eb46694f484 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)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
			/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
			 * turn OFF  the TRANSMISSION of PAUSE frames.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
			 */
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
				hw->fc.current_mode = e1000_fc_full;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
				e_dbg("Flow Control = FULL.\r\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
			} else {
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
				e_dbg("Flow Control = "
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
					 "RX PAUSE frames only.\r\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
			}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
		/*
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
		 * For receiving PAUSE frames ONLY.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
		 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
		 *   LOCAL DEVICE  |   LINK PARTNER
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		 *-------|---------|-------|---------|--------------------
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
		 */
2eb46694f484 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) &&
2eb46694f484 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) &&
2eb46694f484 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) &&
2eb46694f484 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)) {
2eb46694f484 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;
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		/*
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
		 * For transmitting PAUSE frames ONLY.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
		 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		 *   LOCAL DEVICE  |   LINK PARTNER
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		 *-------|---------|-------|---------|--------------------
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		 */
2eb46694f484 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) &&
2eb46694f484 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) &&
2eb46694f484 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) &&
2eb46694f484 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)) {
2eb46694f484 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;
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
			/*
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
			 * should be disabled.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
			 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
			hw->fc.current_mode = e1000_fc_none;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
			e_dbg("Flow Control = NONE.\r\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		/*
2eb46694f484 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-
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		 * enabled per IEEE 802.3 spec.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		if (ret_val) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
		if (duplex == HALF_DUPLEX)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
			hw->fc.current_mode = e1000_fc_none;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		/*
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
		 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
		ret_val = e1000e_force_mac_fc(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
		if (ret_val) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
 *  @speed: stores the current speed
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
 *  @duplex: stores the current duplex
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
 *  speed and duplex for copper connections.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	u32 status;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	status = er32(STATUS);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
	if (status & E1000_STATUS_SPEED_1000) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		*speed = SPEED_1000;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
		e_dbg("1000 Mbs, ");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	} else if (status & E1000_STATUS_SPEED_100) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		*speed = SPEED_100;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		e_dbg("100 Mbs, ");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
	} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
		*speed = SPEED_10;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		e_dbg("10 Mbs, ");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	if (status & E1000_STATUS_FD) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		*duplex = FULL_DUPLEX;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		e_dbg("Full Duplex\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		*duplex = HALF_DUPLEX;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		e_dbg("Half Duplex\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
 *  @speed: stores the current speed
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
 *  @duplex: stores the current duplex
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
 *
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
 *  for fiber/serdes links.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	*speed = SPEED_1000;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	*duplex = FULL_DUPLEX;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
 *  e1000e_get_hw_semaphore - Acquire hardware semaphore
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	u32 swsm;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	s32 timeout = hw->nvm.word_size + 1;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	s32 i = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	/* Get the SW semaphore */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	while (i < timeout) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
		swsm = er32(SWSM);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
		if (!(swsm & E1000_SWSM_SMBI))
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
		udelay(50);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
		i++;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	if (i == timeout) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
		return -E1000_ERR_NVM;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	/* Get the FW semaphore. */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	for (i = 0; i < timeout; i++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
		swsm = er32(SWSM);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
		ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		/* Semaphore acquired if bit latched */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
		if (er32(SWSM) & E1000_SWSM_SWESMBI)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
		udelay(50);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	if (i == timeout) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		/* Release semaphores */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
		e1000e_put_hw_semaphore(hw);
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
		return -E1000_ERR_NVM;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
 *  e1000e_put_hw_semaphore - Release hardware semaphore
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
	u32 swsm;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	swsm = er32(SWSM);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	ew32(SWSM, swsm);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
 *  Check EEPROM for Auto Read done bit.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
	s32 i = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
	while (i < AUTO_READ_DONE_TIMEOUT) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
		if (er32(EECD) & E1000_EECD_AUTO_RD)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
		msleep(1);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
		i++;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	if (i == AUTO_READ_DONE_TIMEOUT) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
		return -E1000_ERR_RESET;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
 *  @data: pointer to the NVM (EEPROM)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
		e_dbg("NVM Read Error\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
		*data = ID_LED_DEFAULT;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
 *  e1000e_id_led_init -
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	struct e1000_mac_info *mac = &hw->mac;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
	const u32 ledctl_mask = 0x000000FF;
2eb46694f484 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;
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	u16 data, i, temp;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
	const u16 led_mask = 0x0F;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	mac->ledctl_default = er32(LEDCTL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	mac->ledctl_mode1 = mac->ledctl_default;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	mac->ledctl_mode2 = mac->ledctl_default;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	for (i = 0; i < 4; i++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
		temp = (data >> (i << 2)) & led_mask;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		switch (temp) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
		case ID_LED_ON1_DEF2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
		case ID_LED_ON1_ON2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
		case ID_LED_ON1_OFF2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
			mac->ledctl_mode1 |= ledctl_on << (i << 3);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		case ID_LED_OFF1_DEF2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
		case ID_LED_OFF1_ON2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
		case ID_LED_OFF1_OFF2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
			mac->ledctl_mode1 |= ledctl_off << (i << 3);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
		default:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
			/* Do nothing */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
		switch (temp) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
		case ID_LED_DEF1_ON2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
		case ID_LED_ON1_ON2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
		case ID_LED_OFF1_ON2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
			mac->ledctl_mode2 |= ledctl_on << (i << 3);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
		case ID_LED_DEF1_OFF2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		case ID_LED_ON1_OFF2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
		case ID_LED_OFF1_OFF2:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
			mac->ledctl_mode2 |= ledctl_off << (i << 3);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
		default:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
			/* Do nothing */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
	u32 ledctl;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
		return -E1000_ERR_CONFIG;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
		ledctl = er32(LEDCTL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		hw->mac.ledctl_default = ledctl;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
		/* Turn off LED0 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
		ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
		            E1000_LEDCTL_LED0_BLINK |
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
		            E1000_LEDCTL_LED0_MODE_MASK);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
		ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
		           E1000_LEDCTL_LED0_MODE_SHIFT);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
		ew32(LEDCTL, ledctl);
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
		ew32(LEDCTL, hw->mac.ledctl_mode1);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	ew32(LEDCTL, hw->mac.ledctl_default);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
 *  e1000e_blink_led - Blink LED
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
 *
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	u32 ledctl_blink = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	u32 i;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
		/* always blink LED0 for PCI-E fiber */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
		ledctl_blink = E1000_LEDCTL_LED0_BLINK |
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
		/*
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
		 * in ledctl_mode2
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
		 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
		ledctl_blink = hw->mac.ledctl_mode2;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
		for (i = 0; i < 4; i++)
2eb46694f484 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) ==
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
			    E1000_LEDCTL_MODE_LED_ON)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
						 (i * 8));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
	ew32(LEDCTL, ledctl_blink);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
 *  e1000e_led_on_generic - Turn LED on
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
 *  Turn LED on.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	u32 ctrl;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
	switch (hw->phy.media_type) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	case e1000_media_type_fiber:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
		ctrl = er32(CTRL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		ctrl &= ~E1000_CTRL_SWDPIN0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
		ctrl |= E1000_CTRL_SWDPIO0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
		ew32(CTRL, ctrl);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	case e1000_media_type_copper:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
		ew32(LEDCTL, hw->mac.ledctl_mode2);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
	default:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
 *  e1000e_led_off_generic - Turn LED off
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
 *  Turn LED off.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	u32 ctrl;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	switch (hw->phy.media_type) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	case e1000_media_type_fiber:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
		ctrl = er32(CTRL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
		ctrl |= E1000_CTRL_SWDPIN0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		ctrl |= E1000_CTRL_SWDPIO0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		ew32(CTRL, ctrl);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
	case e1000_media_type_copper:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
		ew32(LEDCTL, hw->mac.ledctl_mode1);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
	default:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
 *  @no_snoop: bitmap of snoop events
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
 *
2eb46694f484 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'.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	u32 gcr;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
	if (no_snoop) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
		gcr = er32(GCR);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		gcr &= ~(PCIE_NO_SNOOP_ALL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
		gcr |= no_snoop;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		ew32(GCR, gcr);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
 *  Returns 0 if successful, else returns -10
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
 *  the master requests to be disabled.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
 *  requests.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
	u32 ctrl;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	s32 timeout = MASTER_DISABLE_TIMEOUT;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	ctrl = er32(CTRL);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
	ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	ew32(CTRL, ctrl);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	while (timeout) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
		if (!(er32(STATUS) &
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
		      E1000_STATUS_GIO_MASTER_ENABLE))
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		udelay(100);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		timeout--;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	if (!timeout) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		e_dbg("Master requests are pending.\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		return -E1000_ERR_MASTER_REQUESTS_PENDING;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
 *  e1000e_reset_adaptive - Reset Adaptive Interframe Spacing
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
 *
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	struct e1000_mac_info *mac = &hw->mac;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
	if (!mac->adaptive_ifs) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
		goto out;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
	mac->current_ifs_val = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
	mac->ifs_min_val = IFS_MIN;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
	mac->ifs_max_val = IFS_MAX;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
	mac->ifs_step_size = IFS_STEP;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	mac->ifs_ratio = IFS_RATIO;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	mac->in_ifs_mode = false;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	ew32(AIT, 0);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
out:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
	return;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
 *  e1000e_update_adaptive - Update Adaptive Interframe Spacing
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
	struct e1000_mac_info *mac = &hw->mac;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
	if (!mac->adaptive_ifs) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
		goto out;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
2eb46694f484 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) {
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
			mac->in_ifs_mode = true;
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
				if (!mac->current_ifs_val)
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
				else
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
					mac->current_ifs_val +=
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
						mac->ifs_step_size;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
				ew32(AIT, mac->current_ifs_val);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
			}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
		if (mac->in_ifs_mode &&
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
			mac->current_ifs_val = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
			mac->in_ifs_mode = false;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
			ew32(AIT, 0);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
out:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
	return;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
 *  e1000_raise_eec_clk - Raise EEPROM clock
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
 *  @eecd: pointer to the EEPROM
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
 *  Enable/Raise the EEPROM clock bit.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	*eecd = *eecd | E1000_EECD_SK;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	ew32(EECD, *eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	udelay(hw->nvm.delay_usec);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
 *  e1000_lower_eec_clk - Lower EEPROM clock
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
 *  @eecd: pointer to the EEPROM
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
 *  Clear/Lower the EEPROM clock bit.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	*eecd = *eecd & ~E1000_EECD_SK;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	ew32(EECD, *eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
	udelay(hw->nvm.delay_usec);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
 *  @data: data to send to the EEPROM
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
 *  @count: number of bits to shift out
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	struct e1000_nvm_info *nvm = &hw->nvm;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	u32 eecd = er32(EECD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	u32 mask;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	mask = 0x01 << (count - 1);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	if (nvm->type == e1000_nvm_eeprom_spi)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
		eecd |= E1000_EECD_DO;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
	do {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		eecd &= ~E1000_EECD_DI;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		if (data & mask)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
			eecd |= E1000_EECD_DI;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		ew32(EECD, eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		udelay(nvm->delay_usec);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		e1000_raise_eec_clk(hw, &eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		e1000_lower_eec_clk(hw, &eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		mask >>= 1;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
	} while (mask);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
	eecd &= ~E1000_EECD_DI;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	ew32(EECD, eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
 *  @count: number of bits to shift in
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
 *  always be clear.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	u32 eecd;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
	u32 i;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	u16 data;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	eecd = er32(EECD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	data = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	for (i = 0; i < count; i++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
		data <<= 1;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		e1000_raise_eec_clk(hw, &eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
		eecd = er32(EECD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		eecd &= ~E1000_EECD_DI;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		if (eecd & E1000_EECD_DO)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
			data |= 1;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		e1000_lower_eec_clk(hw, &eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
	return data;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
 *  @ee_reg: EEPROM flag for polling
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
 *  upon the value of 'ee_reg'.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
	u32 attempts = 100000;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
	u32 i, reg = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	for (i = 0; i < attempts; i++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
		if (ee_reg == E1000_NVM_POLL_READ)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
			reg = er32(EERD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
		else
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
			reg = er32(EEWR);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		if (reg & E1000_NVM_RW_REG_DONE)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
			return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		udelay(5);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	return -E1000_ERR_NVM;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
 *
2eb46694f484 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.
2eb46694f484 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
2eb46694f484 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).
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	u32 eecd = er32(EECD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	ew32(EECD, eecd | E1000_EECD_REQ);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
	eecd = er32(EECD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	while (timeout) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
		if (eecd & E1000_EECD_GNT)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
		udelay(5);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
		eecd = er32(EECD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		timeout--;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	if (!timeout) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
		eecd &= ~E1000_EECD_REQ;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
		ew32(EECD, eecd);
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
		return -E1000_ERR_NVM;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
 *  Return the EEPROM to a standby state.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
	struct e1000_nvm_info *nvm = &hw->nvm;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	u32 eecd = er32(EECD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	if (nvm->type == e1000_nvm_eeprom_spi) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
		/* Toggle CS to flush commands */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
		eecd |= E1000_EECD_CS;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
		ew32(EECD, eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
		e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
		udelay(nvm->delay_usec);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
		eecd &= ~E1000_EECD_CS;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		ew32(EECD, eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
		udelay(nvm->delay_usec);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
 *  e1000_stop_nvm - Terminate EEPROM command
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
 *
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	u32 eecd;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	eecd = er32(EECD);
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		/* Pull CS high */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		eecd |= E1000_EECD_CS;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
		e1000_lower_eec_clk(hw, &eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
 *
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	u32 eecd;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
	e1000_stop_nvm(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
	eecd = er32(EECD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	eecd &= ~E1000_EECD_REQ;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
	ew32(EECD, eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
 *
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
 *  Setups the EEPROM for reading and writing.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
	struct e1000_nvm_info *nvm = &hw->nvm;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	u32 eecd = er32(EECD);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
	u16 timeout = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	u8 spi_stat_reg;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	if (nvm->type == e1000_nvm_eeprom_spi) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
		/* Clear SK and CS */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
		ew32(EECD, eecd);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
		udelay(1);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
		timeout = NVM_MAX_RETRY_SPI;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
		/*
2eb46694f484 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.
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
		 * not cleared within 'timeout', then error out.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
		 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
		while (timeout) {
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
						 hw->nvm.opcode_bits);
2eb46694f484 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);
2eb46694f484 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))
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
				break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
			udelay(5);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
			e1000_standby_nvm(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
			timeout--;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
		if (!timeout) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
			e_dbg("SPI NVM Status error\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
			return -E1000_ERR_NVM;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
 *  @hw: pointer to the HW structure
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
 *  @words: number of words to read
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
 *  @data: word read from the EEPROM
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
 *
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	struct e1000_nvm_info *nvm = &hw->nvm;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	u32 i, eerd = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	s32 ret_val = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	/*
2eb46694f484 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,
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
	 */
2eb46694f484 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)) ||
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
	    (words == 0)) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
		return -E1000_ERR_NVM;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
	for (i = 0; i < words; i++) {
2eb46694f484 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) +
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
		       E1000_NVM_RW_REG_START;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
		ew32(EERD, eerd);
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
		if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
	return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
 *  @hw: pointer to the HW structure
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
 *  @words: number of words to write
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
 *
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	struct e1000_nvm_info *nvm = &hw->nvm;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	u16 widx = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	/*
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
	 * and not enough words.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
	 */
2eb46694f484 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)) ||
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	    (words == 0)) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
		return -E1000_ERR_NVM;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	ret_val = nvm->ops.acquire(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
	if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	msleep(10);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	while (widx < words) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
		u8 write_opcode = NVM_WRITE_OPCODE_SPI;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
		ret_val = e1000_ready_nvm_eeprom(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
		if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
			nvm->ops.release(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
		e1000_standby_nvm(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
2eb46694f484 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) */
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
					 nvm->opcode_bits);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		e1000_standby_nvm(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
		/*
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
		 * opcode
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
		 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
		if ((nvm->address_bits == 8) && (offset >= 128))
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
			write_opcode |= NVM_A8_OPCODE_SPI;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
2eb46694f484 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) */
2eb46694f484 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);
2eb46694f484 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),
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
					 nvm->address_bits);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
2eb46694f484 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 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		while (widx < words) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
			u16 word_out = data[widx];
2eb46694f484 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);
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			widx++;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
				e1000_standby_nvm(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
				break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
			}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	msleep(10);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	nvm->ops.release(hw);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
 *
2eb46694f484 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.
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
	u16 offset, nvm_data, i;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
	u16 mac_addr_offset = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
	if (hw->mac.type == e1000_82571) {
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
		 * actual permanent MAC address.*/
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
					 &mac_addr_offset);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
		if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
			e_dbg("NVM Read Error\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
		if (mac_addr_offset == 0xFFFF)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
			mac_addr_offset = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
		if (mac_addr_offset) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
			if (hw->bus.func == E1000_FUNC_1)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
				mac_addr_offset += ETH_ALEN/sizeof(u16);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
			* before using it */
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
						 &nvm_data);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
			if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
				e_dbg("NVM Read Error\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
				return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
			}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
			if (nvm_data & 0x0001)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
				mac_addr_offset = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
		if (mac_addr_offset)
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
2eb46694f484 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) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
		offset = mac_addr_offset + (i >> 1);
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
		if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
			e_dbg("NVM Read Error\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
		}
2eb46694f484 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);
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
2eb46694f484 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 */
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
		hw->mac.perm_addr[5] ^= 1;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	for (i = 0; i < ETH_ALEN; i++)
2eb46694f484 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];
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
 *
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	u16 checksum = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	u16 i, nvm_data;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
2eb46694f484 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++) {
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
		if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
			e_dbg("NVM Read Error\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
		checksum += nvm_data;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	if (checksum != (u16) NVM_SUM) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
		e_dbg("NVM Checksum Invalid\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
		return -E1000_ERR_NVM;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
 *  value to the EEPROM.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
	u16 checksum = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	u16 i, nvm_data;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
2eb46694f484 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++) {
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
		if (ret_val) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
		checksum += nvm_data;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	checksum = (u16) NVM_SUM - checksum;
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	if (ret_val)
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
 *  e1000e_reload_nvm - Reloads EEPROM
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
 *  extended control register.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	u32 ctrl_ext;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	udelay(10);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
	ctrl_ext = er32(CTRL_EXT);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	ctrl_ext |= E1000_CTRL_EXT_EE_RST;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	ew32(CTRL_EXT, ctrl_ext);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
/**
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
 *  e1000_calculate_checksum - Calculate checksum for buffer
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
 *  @buffer: pointer to EEPROM
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
 *  checksum calculated is returned.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
	u32 i;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	u8  sum = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	if (!buffer)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
		return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	for (i = 0; i < length; i++)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
		sum += buffer[i];
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	return (u8) (0 - sum);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
 *
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	u32 hicr;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	u8 i;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
	/* Check that the host interface is enabled. */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	hicr = er32(HICR);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	if ((hicr & E1000_HICR_EN) == 0) {
2eb46694f484 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");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
		return -E1000_ERR_HOST_INTERFACE_COMMAND;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	/* check the previous command is completed */
2eb46694f484 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++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
		hicr = er32(HICR);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
		if (!(hicr & E1000_HICR_C))
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
			break;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
		mdelay(1);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
	if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
		e_dbg("Previous command timeout failed .\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
		return -E1000_ERR_HOST_INTERFACE_COMMAND;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
 *  manageability is enabled, else false (0).
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	u32 fwsm = er32(FWSM);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	return (fwsm & E1000_FWSM_MODE_MASK) ==
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
 *
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
 *  and host interface is enabled.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
{
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	u32 *buffer = (u32 *)&hw->mng_cookie;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	u32 offset;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	s32 ret_val, hdr_csum, csum;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	u8 i, len;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	hw->mac.tx_pkt_filtering = true;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	/* No manageability, no filtering */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	if (!e1000e_check_mng_mode(hw)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
		hw->mac.tx_pkt_filtering = false;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
		goto out;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	/*
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
	 * reason, disable filtering.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	 */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
		hw->mac.tx_pkt_filtering = false;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
		goto out;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
2eb46694f484 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. */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
	len    = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
	for (i = 0; i < len; i++)
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
	hdr_csum = hdr->checksum;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
	hdr->checksum = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	csum = e1000_calculate_checksum((u8 *)hdr,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
					E1000_MNG_DHCP_COOKIE_LENGTH);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
	/*
2eb46694f484 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
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	 */
2eb46694f484 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)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		hw->mac.tx_pkt_filtering = true;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
		goto out;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
2eb46694f484 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. */
2eb46694f484 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)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
		hw->mac.tx_pkt_filtering = false;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
		goto out;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
out:
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	return hw->mac.tx_pkt_filtering;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
 *  @hw: pointer to the HW structure
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
 *
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
 **/
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
				  struct e1000_host_mng_command_header *hdr)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
{
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
2eb46694f484 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. */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	length >>= 2;
2eb46694f484 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. */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
	for (i = 0; i < length; i++) {
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
					    *((u32 *) hdr + i));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
		e1e_flush();
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
 *  @buffer: pointer to the host interface buffer
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
 *  @length: size of the buffer
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
 *  @sum: sum of the data (not checksum)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
 *
2eb46694f484 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.
2eb46694f484 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
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
 **/
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
				   u16 length, u16 offset, u8 *sum)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	u8 *tmp;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	u8 *bufptr = buffer;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	u32 data = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	u16 remaining, i, j, prev_bytes;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
2eb46694f484 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 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
		return -E1000_ERR_PARAM;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
	tmp = (u8 *)&data;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
	prev_bytes = offset & 0x3;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
	offset >>= 2;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
	if (prev_bytes) {
2eb46694f484 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);
2eb46694f484 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++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
			*(tmp + j) = *bufptr++;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
			*sum += *(tmp + j);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
		}
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
		length -= j - prev_bytes;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
		offset++;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	remaining = length & 0x3;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	length -= remaining;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	/* Calculate length in DWORDs */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
	length >>= 2;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	/*
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
	 * ram area.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	 */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	for (i = 0; i < length; i++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
		for (j = 0; j < sizeof(u32); j++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
			*(tmp + j) = *bufptr++;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
			*sum += *(tmp + j);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	if (remaining) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
		for (j = 0; j < sizeof(u32); j++) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
			if (j < remaining)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
				*(tmp + j) = *bufptr++;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
			else
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
				*(tmp + j) = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
			*sum += *(tmp + j);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
		}
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
 *  @buffer: pointer to the host interface
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
 *  @length: size of the buffer
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
 *
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
	struct e1000_host_mng_command_header hdr;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
	u32 hicr;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
2eb46694f484 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;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	hdr.command_length = length;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
	hdr.reserved1 = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
	hdr.reserved2 = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	hdr.checksum = 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
	/* Enable the host interface */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
	if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
2eb46694f484 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". */
2eb46694f484 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,
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
					  sizeof(hdr), &(hdr.checksum));
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	/* Write the manageability command header */
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	if (ret_val)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
2eb46694f484 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. */
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
	hicr = er32(HICR);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	ew32(HICR, hicr | E1000_HICR_C);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
/**
2eb46694f484 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
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
 *  @hw: pointer to the HW structure
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
 *
2eb46694f484 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.
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
 **/
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
	u32 manc;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
	u32 fwsm, factps;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
	bool ret_val = false;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
	manc = er32(MANC);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
	if (!(manc & E1000_MANC_RCV_TCO_EN) ||
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	    !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	if (hw->mac.arc_subsystem_valid) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
		fwsm = er32(FWSM);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
		factps = er32(FACTPS);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
		if (!(factps & E1000_FACTPS_MNGCG) &&
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		    ((fwsm & E1000_FWSM_MODE_MASK) ==
2eb46694f484 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))) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
			ret_val = true;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	} else {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		if ((manc & E1000_MANC_SMBUS_EN) &&
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		    !(manc & E1000_MANC_ASF_EN)) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
			ret_val = true;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
			return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
		}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
2eb46694f484 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)
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
{
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
	s32 ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
	u16 nvm_data;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
	if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
		e_dbg("NVM Read Error\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
	*pba_num = (u32)(nvm_data << 16);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
2eb46694f484 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);
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
	if (ret_val) {
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
		e_dbg("NVM Read Error\n");
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
		return ret_val;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
	}
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	*pba_num |= nvm_data;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	return 0;
2eb46694f484 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
}