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