devices/e1000/e1000_ethtool-2.6.32-orig.c
author Knud Baastrup <kba@deif.com>
Tue, 14 Apr 2015 10:12:55 -0400
changeset 2625 e25af8bd3957
parent 2171 4eff8c9cfbbc
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.
2171
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
4eff8c9cfbbc Added e1000 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
4eff8c9cfbbc Added e1000 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,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
4eff8c9cfbbc Added e1000 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
4eff8c9cfbbc Added e1000 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
4eff8c9cfbbc Added e1000 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
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
4eff8c9cfbbc Added e1000 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
4eff8c9cfbbc Added e1000 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.,
4eff8c9cfbbc Added e1000 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.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
4eff8c9cfbbc Added e1000 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
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
4eff8c9cfbbc Added e1000 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
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
/* ethtool support for e1000 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include "e1000.h"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <asm/uaccess.h>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
struct e1000_stats {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
	char stat_string[ETH_GSTRING_LEN];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
	int sizeof_stat;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
	int stat_offset;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#define E1000_STAT(m) FIELD_SIZEOF(struct e1000_adapter, m), \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
		      offsetof(struct e1000_adapter, m)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
static const struct e1000_stats e1000_gstrings_stats[] = {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
	{ "rx_packets", E1000_STAT(stats.gprc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
	{ "tx_packets", E1000_STAT(stats.gptc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
	{ "rx_bytes", E1000_STAT(stats.gorcl) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	{ "tx_bytes", E1000_STAT(stats.gotcl) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
	{ "rx_broadcast", E1000_STAT(stats.bprc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	{ "tx_broadcast", E1000_STAT(stats.bptc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	{ "rx_multicast", E1000_STAT(stats.mprc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	{ "tx_multicast", E1000_STAT(stats.mptc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	{ "rx_errors", E1000_STAT(stats.rxerrc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	{ "tx_errors", E1000_STAT(stats.txerrc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	{ "tx_dropped", E1000_STAT(net_stats.tx_dropped) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	{ "multicast", E1000_STAT(stats.mprc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	{ "collisions", E1000_STAT(stats.colc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	{ "rx_length_errors", E1000_STAT(stats.rlerrc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	{ "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	{ "rx_crc_errors", E1000_STAT(stats.crcerrs) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	{ "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	{ "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	{ "rx_missed_errors", E1000_STAT(stats.mpc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	{ "tx_aborted_errors", E1000_STAT(stats.ecol) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	{ "tx_carrier_errors", E1000_STAT(stats.tncrs) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	{ "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	{ "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	{ "tx_window_errors", E1000_STAT(stats.latecol) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	{ "tx_abort_late_coll", E1000_STAT(stats.latecol) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	{ "tx_deferred_ok", E1000_STAT(stats.dc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	{ "tx_single_coll_ok", E1000_STAT(stats.scc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	{ "tx_multi_coll_ok", E1000_STAT(stats.mcc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	{ "tx_timeout_count", E1000_STAT(tx_timeout_count) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	{ "tx_restart_queue", E1000_STAT(restart_queue) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	{ "rx_long_length_errors", E1000_STAT(stats.roc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	{ "rx_short_length_errors", E1000_STAT(stats.ruc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	{ "rx_align_errors", E1000_STAT(stats.algnerrc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	{ "tx_tcp_seg_good", E1000_STAT(stats.tsctc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	{ "tx_tcp_seg_failed", E1000_STAT(stats.tsctfc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	{ "rx_flow_control_xon", E1000_STAT(stats.xonrxc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	{ "rx_flow_control_xoff", E1000_STAT(stats.xoffrxc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	{ "tx_flow_control_xon", E1000_STAT(stats.xontxc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	{ "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	{ "rx_long_byte_count", E1000_STAT(stats.gorcl) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	{ "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	{ "tx_smbus", E1000_STAT(stats.mgptc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
	{ "rx_smbus", E1000_STAT(stats.mgprc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
	{ "dropped_smbus", E1000_STAT(stats.mgpdc) },
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
#define E1000_QUEUE_STATS_LEN 0
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
#define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
#define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN + E1000_QUEUE_STATS_LEN)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
	"Register test  (offline)", "Eeprom test    (offline)",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	"Interrupt test (offline)", "Loopback test  (offline)",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
	"Link test   (on/offline)"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
#define E1000_TEST_LEN	ARRAY_SIZE(e1000_gstrings_test)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
static int e1000_get_settings(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
			      struct ethtool_cmd *ecmd)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	if (hw->media_type == e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
		ecmd->supported = (SUPPORTED_10baseT_Half |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
		                   SUPPORTED_10baseT_Full |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
		                   SUPPORTED_100baseT_Half |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
		                   SUPPORTED_100baseT_Full |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
		                   SUPPORTED_1000baseT_Full|
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
		                   SUPPORTED_Autoneg |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
		                   SUPPORTED_TP);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
		ecmd->advertising = ADVERTISED_TP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
		if (hw->autoneg == 1) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
			ecmd->advertising |= ADVERTISED_Autoneg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
			/* the e1000 autoneg seems to match ethtool nicely */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
			ecmd->advertising |= hw->autoneg_advertised;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
		ecmd->port = PORT_TP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
		ecmd->phy_address = hw->phy_addr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
		if (hw->mac_type == e1000_82543)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
			ecmd->transceiver = XCVR_EXTERNAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
			ecmd->transceiver = XCVR_INTERNAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
		ecmd->supported   = (SUPPORTED_1000baseT_Full |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
				     SUPPORTED_FIBRE |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
				     SUPPORTED_Autoneg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
		ecmd->advertising = (ADVERTISED_1000baseT_Full |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
				     ADVERTISED_FIBRE |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
				     ADVERTISED_Autoneg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
		ecmd->port = PORT_FIBRE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
		if (hw->mac_type >= e1000_82545)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
			ecmd->transceiver = XCVR_INTERNAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
			ecmd->transceiver = XCVR_EXTERNAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
	if (er32(STATUS) & E1000_STATUS_LU) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
		e1000_get_speed_and_duplex(hw, &adapter->link_speed,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
		                                   &adapter->link_duplex);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
		ecmd->speed = adapter->link_speed;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
		/* unfortunatly FULL_DUPLEX != DUPLEX_FULL
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
		 *          and HALF_DUPLEX != DUPLEX_HALF */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
		if (adapter->link_duplex == FULL_DUPLEX)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
			ecmd->duplex = DUPLEX_FULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
			ecmd->duplex = DUPLEX_HALF;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
		ecmd->speed = -1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
		ecmd->duplex = -1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
	ecmd->autoneg = ((hw->media_type == e1000_media_type_fiber) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
			 hw->autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
static int e1000_set_settings(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
			      struct ethtool_cmd *ecmd)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
		msleep(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
	if (ecmd->autoneg == AUTONEG_ENABLE) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
		hw->autoneg = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
		if (hw->media_type == e1000_media_type_fiber)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
			hw->autoneg_advertised = ADVERTISED_1000baseT_Full |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
				     ADVERTISED_FIBRE |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
				     ADVERTISED_Autoneg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
			hw->autoneg_advertised = ecmd->advertising |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
			                         ADVERTISED_TP |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
			                         ADVERTISED_Autoneg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
		ecmd->advertising = hw->autoneg_advertised;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
	} else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
		if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
			clear_bit(__E1000_RESETTING, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
			return -EINVAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	/* reset the link */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	if (netif_running(adapter->netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
		e1000_down(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
		e1000_up(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	} else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
		e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	clear_bit(__E1000_RESETTING, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
static void e1000_get_pauseparam(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
				 struct ethtool_pauseparam *pause)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	pause->autoneg =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
		(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
	if (hw->fc == E1000_FC_RX_PAUSE)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
		pause->rx_pause = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	else if (hw->fc == E1000_FC_TX_PAUSE)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
		pause->tx_pause = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	else if (hw->fc == E1000_FC_FULL) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
		pause->rx_pause = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
		pause->tx_pause = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
static int e1000_set_pauseparam(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
				struct ethtool_pauseparam *pause)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	int retval = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	adapter->fc_autoneg = pause->autoneg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
		msleep(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	if (pause->rx_pause && pause->tx_pause)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
		hw->fc = E1000_FC_FULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	else if (pause->rx_pause && !pause->tx_pause)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
		hw->fc = E1000_FC_RX_PAUSE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	else if (!pause->rx_pause && pause->tx_pause)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
		hw->fc = E1000_FC_TX_PAUSE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	else if (!pause->rx_pause && !pause->tx_pause)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
		hw->fc = E1000_FC_NONE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	hw->original_fc = hw->fc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	if (adapter->fc_autoneg == AUTONEG_ENABLE) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
		if (netif_running(adapter->netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
			e1000_down(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
			e1000_up(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
		} else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
			e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	} else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
		retval = ((hw->media_type == e1000_media_type_fiber) ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
			  e1000_setup_link(hw) : e1000_force_mac_fc(hw));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	clear_bit(__E1000_RESETTING, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	return retval;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
static u32 e1000_get_rx_csum(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	return adapter->rx_csum;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
static int e1000_set_rx_csum(struct net_device *netdev, u32 data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	adapter->rx_csum = data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	if (netif_running(netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		e1000_reinit_locked(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
static u32 e1000_get_tx_csum(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	return (netdev->features & NETIF_F_HW_CSUM) != 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
static int e1000_set_tx_csum(struct net_device *netdev, u32 data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	if (hw->mac_type < e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		if (!data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
			return -EINVAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
		return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	if (data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
		netdev->features |= NETIF_F_HW_CSUM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
		netdev->features &= ~NETIF_F_HW_CSUM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
static int e1000_set_tso(struct net_device *netdev, u32 data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	if ((hw->mac_type < e1000_82544) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	    (hw->mac_type == e1000_82547))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
		return data ? -EINVAL : 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	if (data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
		netdev->features |= NETIF_F_TSO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
		netdev->features &= ~NETIF_F_TSO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	netdev->features &= ~NETIF_F_TSO6;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	DPRINTK(PROBE, INFO, "TSO is %s\n", data ? "Enabled" : "Disabled");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	adapter->tso_force = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
static u32 e1000_get_msglevel(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	return adapter->msg_enable;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
static void e1000_set_msglevel(struct net_device *netdev, u32 data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	adapter->msg_enable = data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
static int e1000_get_regs_len(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
#define E1000_REGS_LEN 32
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	return E1000_REGS_LEN * sizeof(u32);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
static void e1000_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
			   void *p)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
	u32 *regs_buff = p;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	u16 phy_data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	memset(p, 0, E1000_REGS_LEN * sizeof(u32));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
	regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
	regs_buff[0]  = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	regs_buff[1]  = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
	regs_buff[2]  = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
	regs_buff[3]  = er32(RDLEN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	regs_buff[4]  = er32(RDH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	regs_buff[5]  = er32(RDT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	regs_buff[6]  = er32(RDTR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	regs_buff[7]  = er32(TCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	regs_buff[8]  = er32(TDLEN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	regs_buff[9]  = er32(TDH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	regs_buff[10] = er32(TDT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	regs_buff[11] = er32(TIDV);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
	regs_buff[12] = hw->phy_type;  /* PHY type (IGP=1, M88=0) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	if (hw->phy_type == e1000_phy_igp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
				    IGP01E1000_PHY_AGC_A);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
		e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_A &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
		regs_buff[13] = (u32)phy_data; /* cable length */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
				    IGP01E1000_PHY_AGC_B);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
		e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_B &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
		regs_buff[14] = (u32)phy_data; /* cable length */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
				    IGP01E1000_PHY_AGC_C);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
		e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_C &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
		regs_buff[15] = (u32)phy_data; /* cable length */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
				    IGP01E1000_PHY_AGC_D);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_D &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		regs_buff[16] = (u32)phy_data; /* cable length */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
		regs_buff[17] = 0; /* extended 10bt distance (not needed) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
		regs_buff[18] = (u32)phy_data; /* cable polarity */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
				    IGP01E1000_PHY_PCS_INIT_REG);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
		e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
				   IGP01E1000_PHY_PAGE_SELECT, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
		regs_buff[19] = (u32)phy_data; /* cable polarity */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
		regs_buff[20] = 0; /* polarity correction enabled (always) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
		regs_buff[22] = 0; /* phy receive errors (unavailable) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
		regs_buff[23] = regs_buff[18]; /* mdix mode */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
		e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
		e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
		regs_buff[13] = (u32)phy_data; /* cable length */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
		regs_buff[14] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
		regs_buff[15] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
		regs_buff[16] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
		e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
		regs_buff[17] = (u32)phy_data; /* extended 10bt distance */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
		regs_buff[18] = regs_buff[13]; /* cable polarity */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
		regs_buff[19] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
		regs_buff[20] = regs_buff[17]; /* polarity correction */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
		/* phy receive errors */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
		regs_buff[22] = adapter->phy_stats.receive_errors;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
		regs_buff[23] = regs_buff[13]; /* mdix mode */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	regs_buff[21] = adapter->phy_stats.idle_errors;  /* phy idle errors */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
	regs_buff[24] = (u32)phy_data;  /* phy local receiver status */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	regs_buff[25] = regs_buff[24];  /* phy remote receiver status */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	if (hw->mac_type >= e1000_82540 &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	    hw->media_type == e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
		regs_buff[26] = er32(MANC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
static int e1000_get_eeprom_len(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
	return hw->eeprom.word_size * 2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
static int e1000_get_eeprom(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
			    struct ethtool_eeprom *eeprom, u8 *bytes)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	u16 *eeprom_buff;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	int first_word, last_word;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	int ret_val = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	u16 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	if (eeprom->len == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
		return -EINVAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	first_word = eeprom->offset >> 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
	eeprom_buff = kmalloc(sizeof(u16) *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
			(last_word - first_word + 1), GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	if (!eeprom_buff)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		return -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	if (hw->eeprom.type == e1000_eeprom_spi)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
		ret_val = e1000_read_eeprom(hw, first_word,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
					    last_word - first_word + 1,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
					    eeprom_buff);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
		for (i = 0; i < last_word - first_word + 1; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
			ret_val = e1000_read_eeprom(hw, first_word + i, 1,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
						    &eeprom_buff[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
			if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	/* Device's eeprom is always little-endian, word addressable */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
	for (i = 0; i < last_word - first_word + 1; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		le16_to_cpus(&eeprom_buff[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
			eeprom->len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	kfree(eeprom_buff);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
static int e1000_set_eeprom(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
			    struct ethtool_eeprom *eeprom, u8 *bytes)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	u16 *eeprom_buff;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	void *ptr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	int max_len, first_word, last_word, ret_val = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	u16 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	if (eeprom->len == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
		return -EOPNOTSUPP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		return -EFAULT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	max_len = hw->eeprom.word_size * 2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	first_word = eeprom->offset >> 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	eeprom_buff = kmalloc(max_len, GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
	if (!eeprom_buff)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		return -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	ptr = (void *)eeprom_buff;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	if (eeprom->offset & 1) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
		/* need read/modify/write of first changed EEPROM word */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
		/* only the second byte of the word is being modified */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
		ret_val = e1000_read_eeprom(hw, first_word, 1,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
					    &eeprom_buff[0]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
		ptr++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
		/* need read/modify/write of last changed EEPROM word */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
		/* only the first byte of the word is being modified */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		ret_val = e1000_read_eeprom(hw, last_word, 1,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		                  &eeprom_buff[last_word - first_word]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	/* Device's eeprom is always little-endian, word addressable */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	for (i = 0; i < last_word - first_word + 1; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
		le16_to_cpus(&eeprom_buff[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	memcpy(ptr, bytes, eeprom->len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	for (i = 0; i < last_word - first_word + 1; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
		eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	ret_val = e1000_write_eeprom(hw, first_word,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
				     last_word - first_word + 1, eeprom_buff);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	/* Update the checksum over the first part of the EEPROM if needed */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	if ((ret_val == 0) && (first_word <= EEPROM_CHECKSUM_REG))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
		e1000_update_eeprom_checksum(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	kfree(eeprom_buff);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
static void e1000_get_drvinfo(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
			      struct ethtool_drvinfo *drvinfo)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	char firmware_version[32];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	strncpy(drvinfo->driver,  e1000_driver_name, 32);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	strncpy(drvinfo->version, e1000_driver_version, 32);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	sprintf(firmware_version, "N/A");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	strncpy(drvinfo->fw_version, firmware_version, 32);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	drvinfo->regdump_len = e1000_get_regs_len(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
	drvinfo->eedump_len = e1000_get_eeprom_len(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
static void e1000_get_ringparam(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
				struct ethtool_ringparam *ring)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
	e1000_mac_type mac_type = hw->mac_type;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
	struct e1000_tx_ring *txdr = adapter->tx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	struct e1000_rx_ring *rxdr = adapter->rx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
		E1000_MAX_82544_RXD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	ring->tx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_TXD :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
		E1000_MAX_82544_TXD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	ring->rx_mini_max_pending = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	ring->rx_jumbo_max_pending = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	ring->rx_pending = rxdr->count;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	ring->tx_pending = txdr->count;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	ring->rx_mini_pending = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	ring->rx_jumbo_pending = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
static int e1000_set_ringparam(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
			       struct ethtool_ringparam *ring)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	e1000_mac_type mac_type = hw->mac_type;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	struct e1000_tx_ring *txdr, *tx_old;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	struct e1000_rx_ring *rxdr, *rx_old;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	int i, err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		return -EINVAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		msleep(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	if (netif_running(adapter->netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		e1000_down(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	tx_old = adapter->tx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	rx_old = adapter->rx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	err = -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	txdr = kcalloc(adapter->num_tx_queues, sizeof(struct e1000_tx_ring), GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	if (!txdr)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
		goto err_alloc_tx;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	rxdr = kcalloc(adapter->num_rx_queues, sizeof(struct e1000_rx_ring), GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	if (!rxdr)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
		goto err_alloc_rx;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	adapter->tx_ring = txdr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	adapter->rx_ring = rxdr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	rxdr->count = max(ring->rx_pending,(u32)E1000_MIN_RXD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
	rxdr->count = min(rxdr->count,(u32)(mac_type < e1000_82544 ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
		E1000_MAX_RXD : E1000_MAX_82544_RXD));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	rxdr->count = ALIGN(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	txdr->count = max(ring->tx_pending,(u32)E1000_MIN_TXD);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
	txdr->count = min(txdr->count,(u32)(mac_type < e1000_82544 ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		E1000_MAX_TXD : E1000_MAX_82544_TXD));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	txdr->count = ALIGN(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	for (i = 0; i < adapter->num_tx_queues; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		txdr[i].count = txdr->count;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	for (i = 0; i < adapter->num_rx_queues; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		rxdr[i].count = rxdr->count;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	if (netif_running(adapter->netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
		/* Try to get new resources before deleting old */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
		err = e1000_setup_all_rx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
		if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
			goto err_setup_rx;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
		err = e1000_setup_all_tx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
		if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
			goto err_setup_tx;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
		/* save the new, restore the old in order to free it,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		 * then restore the new back again */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		adapter->rx_ring = rx_old;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		adapter->tx_ring = tx_old;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		e1000_free_all_rx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		e1000_free_all_tx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
		kfree(tx_old);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
		kfree(rx_old);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
		adapter->rx_ring = rxdr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
		adapter->tx_ring = txdr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
		err = e1000_up(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
			goto err_setup;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	clear_bit(__E1000_RESETTING, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
err_setup_tx:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	e1000_free_all_rx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
err_setup_rx:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	adapter->rx_ring = rx_old;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	adapter->tx_ring = tx_old;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
	kfree(rxdr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
err_alloc_rx:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	kfree(txdr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
err_alloc_tx:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	e1000_up(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
err_setup:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	clear_bit(__E1000_RESETTING, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	return err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, int reg,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
			     u32 mask, u32 write)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	static const u32 test[] =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
		{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	u8 __iomem *address = hw->hw_addr + reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	u32 read;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
	int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	for (i = 0; i < ARRAY_SIZE(test); i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		writel(write & test[i], address);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
		read = readl(address);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		if (read != (write & test[i] & mask)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
			DPRINTK(DRV, ERR, "pattern test reg %04X failed: "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
				"got 0x%08X expected 0x%08X\n",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
				reg, read, (write & test[i] & mask));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
			*data = reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
			return true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	return false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data, int reg,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
			      u32 mask, u32 write)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
	u8 __iomem *address = hw->hw_addr + reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	u32 read;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	writel(write & mask, address);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	read = readl(address);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	if ((read & mask) != (write & mask)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
		DPRINTK(DRV, ERR, "set/check reg %04X test failed: "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
			"got 0x%08X expected 0x%08X\n",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
			reg, (read & mask), (write & mask));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
		*data = reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
		return true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	return false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
#define REG_PATTERN_TEST(reg, mask, write)			     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	do {							     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
		if (reg_pattern_test(adapter, data,		     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
			     (hw->mac_type >= e1000_82543)   \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
			     ? E1000_##reg : E1000_82542_##reg,	     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
			     mask, write))			     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
			return 1;				     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	} while (0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
#define REG_SET_AND_CHECK(reg, mask, write)			     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	do {							     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
		if (reg_set_and_check(adapter, data,		     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
			      (hw->mac_type >= e1000_82543)  \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
			      ? E1000_##reg : E1000_82542_##reg,     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
			      mask, write))			     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
			return 1;				     \
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	} while (0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	u32 value, before, after;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	u32 i, toggle;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	/* The status register is Read Only, so a write should fail.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	 * Some bits that get toggled are ignored.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	/* there are several bits on newer hardware that are r/w */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	toggle = 0xFFFFF833;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	before = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	value = (er32(STATUS) & toggle);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	ew32(STATUS, toggle);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	after = er32(STATUS) & toggle;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	if (value != after) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
		DPRINTK(DRV, ERR, "failed STATUS register test got: "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
		        "0x%08X expected: 0x%08X\n", after, value);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
		*data = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
		return 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	/* restore previous status */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	ew32(STATUS, before);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	REG_PATTERN_TEST(FCT, 0x0000FFFF, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	REG_PATTERN_TEST(VET, 0x0000FFFF, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	REG_PATTERN_TEST(RDTR, 0x0000FFFF, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	REG_PATTERN_TEST(RDBAH, 0xFFFFFFFF, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	REG_PATTERN_TEST(RDLEN, 0x000FFF80, 0x000FFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	REG_PATTERN_TEST(RDH, 0x0000FFFF, 0x0000FFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	REG_PATTERN_TEST(RDT, 0x0000FFFF, 0x0000FFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	REG_PATTERN_TEST(FCRTH, 0x0000FFF8, 0x0000FFF8);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	REG_PATTERN_TEST(FCTTV, 0x0000FFFF, 0x0000FFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	REG_PATTERN_TEST(TIPG, 0x3FFFFFFF, 0x3FFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	REG_PATTERN_TEST(TDBAH, 0xFFFFFFFF, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	REG_PATTERN_TEST(TDLEN, 0x000FFF80, 0x000FFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x00000000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	before = 0x06DFB3FE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	REG_SET_AND_CHECK(RCTL, before, 0x003FFFFB);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	REG_SET_AND_CHECK(TCTL, 0xFFFFFFFF, 0x00000000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	if (hw->mac_type >= e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		REG_SET_AND_CHECK(RCTL, before, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
		REG_PATTERN_TEST(RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
		REG_PATTERN_TEST(TXCW, 0xC000FFFF, 0x0000FFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
		REG_PATTERN_TEST(TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
		REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
		value = E1000_RAR_ENTRIES;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
		for (i = 0; i < value; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
			REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
			                 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
		REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x01FFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
		REG_PATTERN_TEST(RDBAL, 0xFFFFF000, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
		REG_PATTERN_TEST(TXCW, 0x0000FFFF, 0x0000FFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
		REG_PATTERN_TEST(TDBAL, 0xFFFFF000, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	value = E1000_MC_TBL_SIZE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	for (i = 0; i < value; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
		REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	*data = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	u16 temp;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
	u16 checksum = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	u16 i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	*data = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	/* Read and add up the contents of the EEPROM */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		if ((e1000_read_eeprom(hw, i, 1, &temp)) < 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
			*data = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
		checksum += temp;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	/* If Checksum is not Correct return error else test passed */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	if ((checksum != (u16)EEPROM_SUM) && !(*data))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
		*data = 2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	return *data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
static irqreturn_t e1000_test_intr(int irq, void *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	struct net_device *netdev = (struct net_device *)data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	adapter->test_icr |= er32(ICR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	return IRQ_HANDLED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	u32 mask, i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	bool shared_int = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	u32 irq = adapter->pdev->irq;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	*data = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	/* NOTE: we don't test MSI interrupts here, yet */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	/* Hook up test interrupt handler just for this test */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	                 netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
		shared_int = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	         netdev->name, netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
		*data = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
		return -1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	DPRINTK(HW, INFO, "testing %s interrupt\n",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	        (shared_int ? "shared" : "unshared"));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	/* Disable all the interrupts */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	ew32(IMC, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	/* Test each interrupt */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	for (; i < 10; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
		/* Interrupt to test */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
		mask = 1 << i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		if (!shared_int) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
			/* Disable the interrupt to be reported in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
			 * the cause register and then force the same
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
			 * interrupt and see if one gets posted.  If
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
			 * an interrupt was posted to the bus, the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
			 * test failed.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
			adapter->test_icr = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
			ew32(IMC, mask);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
			ew32(ICS, mask);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
			msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
			if (adapter->test_icr & mask) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
				*data = 3;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		/* Enable the interrupt to be reported in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
		 * the cause register and then force the same
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
		 * interrupt and see if one gets posted.  If
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		 * an interrupt was not posted to the bus, the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
		 * test failed.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
		adapter->test_icr = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
		ew32(IMS, mask);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
		ew32(ICS, mask);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
		msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
		if (!(adapter->test_icr & mask)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
			*data = 4;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
		if (!shared_int) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
			/* Disable the other interrupts to be reported in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
			 * the cause register and then force the other
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
			 * interrupts and see if any get posted.  If
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
			 * an interrupt was posted to the bus, the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
			 * test failed.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
			adapter->test_icr = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
			ew32(IMC, ~mask & 0x00007FFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
			ew32(ICS, ~mask & 0x00007FFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
			msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
			if (adapter->test_icr) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
				*data = 5;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	/* Disable all the interrupts */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
	ew32(IMC, 0xFFFFFFFF);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	/* Unhook test interrupt handler */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	free_irq(irq, netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	return *data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
static void e1000_free_desc_rings(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	if (txdr->desc && txdr->buffer_info) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
		for (i = 0; i < txdr->count; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
			if (txdr->buffer_info[i].dma)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
				pci_unmap_single(pdev, txdr->buffer_info[i].dma,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
						 txdr->buffer_info[i].length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
						 PCI_DMA_TODEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
			if (txdr->buffer_info[i].skb)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
				dev_kfree_skb(txdr->buffer_info[i].skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	if (rxdr->desc && rxdr->buffer_info) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
		for (i = 0; i < rxdr->count; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
			if (rxdr->buffer_info[i].dma)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
				pci_unmap_single(pdev, rxdr->buffer_info[i].dma,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
						 rxdr->buffer_info[i].length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
						 PCI_DMA_FROMDEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
			if (rxdr->buffer_info[i].skb)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
				dev_kfree_skb(rxdr->buffer_info[i].skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	if (txdr->desc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
		pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		txdr->desc = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	if (rxdr->desc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
		pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
		rxdr->desc = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	kfree(txdr->buffer_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	txdr->buffer_info = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	kfree(rxdr->buffer_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	rxdr->buffer_info = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	u32 rctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	int i, ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	/* Setup Tx descriptor ring and Tx buffers */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	if (!txdr->count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		txdr->count = E1000_DEFAULT_TXD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	txdr->buffer_info = kcalloc(txdr->count, sizeof(struct e1000_buffer),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
				    GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	if (!txdr->buffer_info) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
		ret_val = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
		goto err_nomem;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	txdr->size = ALIGN(txdr->size, 4096);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	if (!txdr->desc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		ret_val = 2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
		goto err_nomem;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	memset(txdr->desc, 0, txdr->size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	txdr->next_to_use = txdr->next_to_clean = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	ew32(TDBAL, ((u64)txdr->dma & 0x00000000FFFFFFFF));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	ew32(TDBAH, ((u64)txdr->dma >> 32));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
	ew32(TDLEN, txdr->count * sizeof(struct e1000_tx_desc));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	ew32(TDH, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	ew32(TDT, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	ew32(TCTL, E1000_TCTL_PSP | E1000_TCTL_EN |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
	     E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	     E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	for (i = 0; i < txdr->count; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*txdr, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
		struct sk_buff *skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		unsigned int size = 1024;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
		skb = alloc_skb(size, GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
		if (!skb) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
			ret_val = 3;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
			goto err_nomem;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		skb_put(skb, size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		txdr->buffer_info[i].skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
		txdr->buffer_info[i].length = skb->len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		txdr->buffer_info[i].dma =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
			pci_map_single(pdev, skb->data, skb->len,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
				       PCI_DMA_TODEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		tx_desc->buffer_addr = cpu_to_le64(txdr->buffer_info[i].dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
		tx_desc->lower.data = cpu_to_le32(skb->len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
		tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
						   E1000_TXD_CMD_IFCS |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
						   E1000_TXD_CMD_RPS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		tx_desc->upper.data = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	/* Setup Rx descriptor ring and Rx buffers */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	if (!rxdr->count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		rxdr->count = E1000_DEFAULT_RXD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	rxdr->buffer_info = kcalloc(rxdr->count, sizeof(struct e1000_buffer),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
				    GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	if (!rxdr->buffer_info) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
		ret_val = 4;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		goto err_nomem;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
	rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	if (!rxdr->desc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		ret_val = 5;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
		goto err_nomem;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	memset(rxdr->desc, 0, rxdr->size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	rxdr->next_to_use = rxdr->next_to_clean = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	ew32(RDBAL, ((u64)rxdr->dma & 0xFFFFFFFF));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	ew32(RDBAH, ((u64)rxdr->dma >> 32));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	ew32(RDLEN, rxdr->size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	ew32(RDH, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	ew32(RDT, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	for (i = 0; i < rxdr->count; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		struct sk_buff *skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		if (!skb) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
			ret_val = 6;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
			goto err_nomem;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		skb_reserve(skb, NET_IP_ALIGN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		rxdr->buffer_info[i].skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		rxdr->buffer_info[i].length = E1000_RXBUFFER_2048;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		rxdr->buffer_info[i].dma =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
			pci_map_single(pdev, skb->data, E1000_RXBUFFER_2048,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
				       PCI_DMA_FROMDEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
		rx_desc->buffer_addr = cpu_to_le64(rxdr->buffer_info[i].dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
		memset(skb->data, 0x00, skb->len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
err_nomem:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	e1000_free_desc_rings(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
static void e1000_phy_disable_receiver(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	/* Write out to PHY registers 29 and 30 to disable the Receiver. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	e1000_write_phy_reg(hw, 29, 0x001F);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
	e1000_write_phy_reg(hw, 30, 0x8FFC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	e1000_write_phy_reg(hw, 29, 0x001A);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
	e1000_write_phy_reg(hw, 30, 0x8FF0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
static void e1000_phy_reset_clk_and_crs(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	u16 phy_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	/* Because we reset the PHY above, we need to re-force TX_CLK in the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
	 * Extended PHY Specific Control Register to 25MHz clock.  This
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	 * value defaults back to a 2.5MHz clock when the PHY is reset.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
	e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
	phy_reg |= M88E1000_EPSCR_TX_CLK_25;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
	e1000_write_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		M88E1000_EXT_PHY_SPEC_CTRL, phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	/* In addition, because of the s/w reset above, we need to enable
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	 * CRS on TX.  This must be set for both full and half duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	 * operation.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	phy_reg |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	e1000_write_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		M88E1000_PHY_SPEC_CTRL, phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
static int e1000_nonintegrated_phy_loopback(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	u32 ctrl_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	u16 phy_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	/* Setup the Device Control Register for PHY loopback test. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	ctrl_reg = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	ctrl_reg |= (E1000_CTRL_ILOS |		/* Invert Loss-Of-Signal */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		     E1000_CTRL_FRCSPD |	/* Set the Force Speed Bit */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		     E1000_CTRL_FRCDPX |	/* Set the Force Duplex Bit */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
		     E1000_CTRL_SPD_1000 |	/* Force Speed to 1000 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
		     E1000_CTRL_FD);		/* Force Duplex to FULL */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	ew32(CTRL, ctrl_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	/* Read the PHY Specific Control Register (0x10) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	/* Clear Auto-Crossover bits in PHY Specific Control Register
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
	 * (bits 6:5).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
	phy_reg &= ~M88E1000_PSCR_AUTO_X_MODE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
	e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
	/* Perform software reset on the PHY */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	e1000_phy_reset(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	/* Have to setup TX_CLK and TX_CRS after software reset */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	e1000_phy_reset_clk_and_crs(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	e1000_write_phy_reg(hw, PHY_CTRL, 0x8100);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	/* Wait for reset to complete. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	udelay(500);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	/* Have to setup TX_CLK and TX_CRS after software reset */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	e1000_phy_reset_clk_and_crs(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	/* Write out to PHY registers 29 and 30 to disable the Receiver. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
	e1000_phy_disable_receiver(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
	/* Set the loopback bit in the PHY control register. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
	e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	phy_reg |= MII_CR_LOOPBACK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
	e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	/* Setup TX_CLK and TX_CRS one more time. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	e1000_phy_reset_clk_and_crs(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
	/* Check Phy Configuration */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
	if (phy_reg != 0x4100)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		 return 9;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	if (phy_reg != 0x0070)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		return 10;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
	e1000_read_phy_reg(hw, 29, &phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	if (phy_reg != 0x001A)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		return 11;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	u32 ctrl_reg = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	u32 stat_reg = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	hw->autoneg = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	if (hw->phy_type == e1000_phy_m88) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		/* Auto-MDI/MDIX Off */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		e1000_write_phy_reg(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
				    M88E1000_PHY_SPEC_CTRL, 0x0808);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		/* reset to update Auto-MDI/MDIX */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		e1000_write_phy_reg(hw, PHY_CTRL, 0x9140);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
		/* autoneg off */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		e1000_write_phy_reg(hw, PHY_CTRL, 0x8140);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
	ctrl_reg = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	/* force 1000, set loopback */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	e1000_write_phy_reg(hw, PHY_CTRL, 0x4140);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
	/* Now set up the MAC to the same speed/duplex as the PHY. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
	ctrl_reg = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
	ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
			E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
			E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
			E1000_CTRL_FD);	 /* Force Duplex to FULL */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	if (hw->media_type == e1000_media_type_copper &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	   hw->phy_type == e1000_phy_m88)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
		ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
		/* Set the ILOS bit on the fiber Nic is half
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
		 * duplex link is detected. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
		stat_reg = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
		if ((stat_reg & E1000_STATUS_FD) == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
			ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	ew32(CTRL, ctrl_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
	/* Disable the receiver on the PHY so when a cable is plugged in, the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	 * PHY does not begin to autoneg when a cable is reconnected to the NIC.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	if (hw->phy_type == e1000_phy_m88)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
		e1000_phy_disable_receiver(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
	udelay(500);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
static int e1000_set_phy_loopback(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	u16 phy_reg = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	u16 count = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	case e1000_82543:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
		if (hw->media_type == e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
			/* Attempt to setup Loopback mode on Non-integrated PHY.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
			 * Some PHY registers get corrupted at random, so
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
			 * attempt this 10 times.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
			while (e1000_nonintegrated_phy_loopback(adapter) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
			      count++ < 10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
			if (count < 11)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
				return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	case e1000_82540:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	case e1000_82545:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	case e1000_82546:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
	case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
		return e1000_integrated_phy_loopback(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
		/* Default PHY loopback work is to read the MII
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
		 * control register and assert bit 14 (loopback mode).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
		e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
		phy_reg |= MII_CR_LOOPBACK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
		e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
		return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
	return 8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
static int e1000_setup_loopback_test(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	u32 rctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	if (hw->media_type == e1000_media_type_fiber ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	    hw->media_type == e1000_media_type_internal_serdes) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
		switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
		case e1000_82545:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
		case e1000_82546:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
		case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
		case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
			return e1000_set_phy_loopback(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
			rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
			rctl |= E1000_RCTL_LBM_TCVR;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
			ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
			return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
	} else if (hw->media_type == e1000_media_type_copper)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
		return e1000_set_phy_loopback(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	return 7;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	u32 rctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	u16 phy_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	case e1000_82545:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	case e1000_82546:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
	case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
		hw->autoneg = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
		e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
		if (phy_reg & MII_CR_LOOPBACK) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
			phy_reg &= ~MII_CR_LOOPBACK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
			e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
			e1000_phy_reset(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
static void e1000_create_lbtest_frame(struct sk_buff *skb,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
				      unsigned int frame_size)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	memset(skb->data, 0xFF, frame_size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	frame_size &= ~1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
static int e1000_check_lbtest_frame(struct sk_buff *skb,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
				    unsigned int frame_size)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	frame_size &= ~1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	if (*(skb->data + 3) == 0xFF) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
		if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		   (*(skb->data + frame_size / 2 + 12) == 0xAF)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
			return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
	return 13;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
static int e1000_run_loopback_test(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
	struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
	int i, j, k, l, lc, good_cnt, ret_val=0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
	unsigned long time;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
	ew32(RDT, rxdr->count - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
	/* Calculate the loop count based on the largest descriptor ring
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	 * The idea is to wrap the largest ring a number of times using 64
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
	 * send/receive pairs during each loop
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	if (rxdr->count <= txdr->count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
		lc = ((txdr->count / 64) * 2) + 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		lc = ((rxdr->count / 64) * 2) + 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	k = l = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	for (j = 0; j <= lc; j++) { /* loop count loop */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
		for (i = 0; i < 64; i++) { /* send the packets */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
			e1000_create_lbtest_frame(txdr->buffer_info[i].skb,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
					1024);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
			pci_dma_sync_single_for_device(pdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
					txdr->buffer_info[k].dma,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
				    	txdr->buffer_info[k].length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
				    	PCI_DMA_TODEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
			if (unlikely(++k == txdr->count)) k = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
		ew32(TDT, k);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
		msleep(200);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
		time = jiffies; /* set the start time for the receive */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
		good_cnt = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
		do { /* receive the sent packets */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
			pci_dma_sync_single_for_cpu(pdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
					rxdr->buffer_info[l].dma,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
				    	rxdr->buffer_info[l].length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
				    	PCI_DMA_FROMDEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
			ret_val = e1000_check_lbtest_frame(
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
					rxdr->buffer_info[l].skb,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
				   	1024);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
			if (!ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
				good_cnt++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
			if (unlikely(++l == rxdr->count)) l = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
			/* time + 20 msecs (200 msecs on 2.4) is more than
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
			 * enough time to complete the receives, if it's
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
			 * exceeded, break and error off
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
			 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
		} while (good_cnt < 64 && jiffies < (time + 20));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
		if (good_cnt != 64) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
			ret_val = 13; /* ret_val is the same as mis-compare */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
		if (jiffies >= (time + 2)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
			ret_val = 14; /* error code for time out error */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	} /* end loop count loop */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	return ret_val;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
	*data = e1000_setup_desc_rings(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	if (*data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
		goto out;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	*data = e1000_setup_loopback_test(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
	if (*data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
		goto err_loopback;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	*data = e1000_run_loopback_test(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	e1000_loopback_cleanup(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
err_loopback:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	e1000_free_desc_rings(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
out:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	return *data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	*data = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	if (hw->media_type == e1000_media_type_internal_serdes) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
		int i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
		hw->serdes_has_link = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
		/* On some blade server designs, link establishment
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
		 * could take as long as 2-3 minutes */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
		do {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
			e1000_check_for_link(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
			if (hw->serdes_has_link)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
				return *data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
			msleep(20);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		} while (i++ < 3750);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
		*data = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		e1000_check_for_link(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
		if (hw->autoneg)  /* if auto_neg is set wait for it */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
			msleep(4000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
		if (!(er32(STATUS) & E1000_STATUS_LU)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
			*data = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	return *data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
static int e1000_get_sset_count(struct net_device *netdev, int sset)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	switch (sset) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	case ETH_SS_TEST:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		return E1000_TEST_LEN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	case ETH_SS_STATS:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
		return E1000_STATS_LEN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
		return -EOPNOTSUPP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
static void e1000_diag_test(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
			    struct ethtool_test *eth_test, u64 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	bool if_running = netif_running(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	set_bit(__E1000_TESTING, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
		/* Offline tests */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
		/* save speed, duplex, autoneg settings */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
		u16 autoneg_advertised = hw->autoneg_advertised;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
		u8 forced_speed_duplex = hw->forced_speed_duplex;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
		u8 autoneg = hw->autoneg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
		DPRINTK(HW, INFO, "offline testing starting\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
		/* Link test performed before hardware reset so autoneg doesn't
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
		 * interfere with test result */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		if (e1000_link_test(adapter, &data[4]))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
			eth_test->flags |= ETH_TEST_FL_FAILED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		if (if_running)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
			/* indicate we're in test mode */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
			dev_close(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
			e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		if (e1000_reg_test(adapter, &data[0]))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
			eth_test->flags |= ETH_TEST_FL_FAILED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		if (e1000_eeprom_test(adapter, &data[1]))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
			eth_test->flags |= ETH_TEST_FL_FAILED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
		e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
		if (e1000_intr_test(adapter, &data[2]))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
			eth_test->flags |= ETH_TEST_FL_FAILED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
		/* make sure the phy is powered up */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		e1000_power_up_phy(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
		if (e1000_loopback_test(adapter, &data[3]))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
			eth_test->flags |= ETH_TEST_FL_FAILED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		/* restore speed, duplex, autoneg settings */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
		hw->autoneg_advertised = autoneg_advertised;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		hw->forced_speed_duplex = forced_speed_duplex;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
		hw->autoneg = autoneg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
		e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
		clear_bit(__E1000_TESTING, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
		if (if_running)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
			dev_open(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
		DPRINTK(HW, INFO, "online testing starting\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
		/* Online tests */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
		if (e1000_link_test(adapter, &data[4]))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
			eth_test->flags |= ETH_TEST_FL_FAILED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
		/* Online tests aren't run; pass by default */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
		data[0] = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
		data[1] = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
		data[2] = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
		data[3] = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
		clear_bit(__E1000_TESTING, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
	msleep_interruptible(4 * 1000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
static int e1000_wol_exclusion(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
			       struct ethtool_wolinfo *wol)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	int retval = 1; /* fail by default */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	switch (hw->device_id) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	case E1000_DEV_ID_82542:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	case E1000_DEV_ID_82543GC_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	case E1000_DEV_ID_82543GC_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	case E1000_DEV_ID_82544EI_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	case E1000_DEV_ID_82545EM_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	case E1000_DEV_ID_82545EM_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	case E1000_DEV_ID_82546GB_QUAD_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	case E1000_DEV_ID_82546GB_PCIE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		/* these don't support WoL at all */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		wol->supported = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
	case E1000_DEV_ID_82546EB_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	case E1000_DEV_ID_82546GB_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
		/* Wake events not supported on port B */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		if (er32(STATUS) & E1000_STATUS_FUNC_1) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
			wol->supported = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
		/* return success for non excluded adapter ports */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
		retval = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		/* quad port adapters only support WoL on port A */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		if (!adapter->quad_port_a) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
			wol->supported = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		/* return success for non excluded adapter ports */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
		retval = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
		/* dual port cards only support WoL on port A from now on
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		 * unless it was enabled in the eeprom for port B
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		 * so exclude FUNC_1 ports from having WoL enabled */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		if (er32(STATUS) & E1000_STATUS_FUNC_1 &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		    !adapter->eeprom_wol) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
			wol->supported = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		retval = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
	return retval;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
static void e1000_get_wol(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
			  struct ethtool_wolinfo *wol)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
	wol->supported = WAKE_UCAST | WAKE_MCAST |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	                 WAKE_BCAST | WAKE_MAGIC;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	wol->wolopts = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	/* this function will set ->supported = 0 and return 1 if wol is not
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	 * supported by this hardware */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
	if (e1000_wol_exclusion(adapter, wol) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	    !device_can_wakeup(&adapter->pdev->dev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
	/* apply any specific unsupported masks here */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	switch (hw->device_id) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
		/* KSP3 does not suppport UCAST wake-ups */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
		wol->supported &= ~WAKE_UCAST;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		if (adapter->wol & E1000_WUFC_EX)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
			DPRINTK(DRV, ERR, "Interface does not support "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		        "directed (unicast) frame wake-up packets\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
	if (adapter->wol & E1000_WUFC_EX)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		wol->wolopts |= WAKE_UCAST;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	if (adapter->wol & E1000_WUFC_MC)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
		wol->wolopts |= WAKE_MCAST;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	if (adapter->wol & E1000_WUFC_BC)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
		wol->wolopts |= WAKE_BCAST;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	if (adapter->wol & E1000_WUFC_MAG)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
		wol->wolopts |= WAKE_MAGIC;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
		return -EOPNOTSUPP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	if (e1000_wol_exclusion(adapter, wol) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	    !device_can_wakeup(&adapter->pdev->dev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		return wol->wolopts ? -EOPNOTSUPP : 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	switch (hw->device_id) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
		if (wol->wolopts & WAKE_UCAST) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
			DPRINTK(DRV, ERR, "Interface does not support "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
		        "directed (unicast) frame wake-up packets\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
			return -EOPNOTSUPP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	/* these settings will always override what we currently have */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	adapter->wol = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	if (wol->wolopts & WAKE_UCAST)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
		adapter->wol |= E1000_WUFC_EX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	if (wol->wolopts & WAKE_MCAST)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
		adapter->wol |= E1000_WUFC_MC;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	if (wol->wolopts & WAKE_BCAST)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
		adapter->wol |= E1000_WUFC_BC;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	if (wol->wolopts & WAKE_MAGIC)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
		adapter->wol |= E1000_WUFC_MAG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
/* toggle LED 4 times per second = 2 "blinks" per second */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
#define E1000_ID_INTERVAL	(HZ/4)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
/* bit defines for adapter->led_status */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
#define E1000_LED_ON		0
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
static void e1000_led_blink_callback(unsigned long data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
	if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		e1000_led_off(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		e1000_led_on(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
	mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
static int e1000_phys_id(struct net_device *netdev, u32 data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	if (!data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		data = INT_MAX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
	if (!adapter->blink_timer.function) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		init_timer(&adapter->blink_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
		adapter->blink_timer.function = e1000_led_blink_callback;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		adapter->blink_timer.data = (unsigned long)adapter;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	e1000_setup_led(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	mod_timer(&adapter->blink_timer, jiffies);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	msleep_interruptible(data * 1000);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	del_timer_sync(&adapter->blink_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	e1000_led_off(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	clear_bit(E1000_LED_ON, &adapter->led_status);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	e1000_cleanup_led(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
static int e1000_get_coalesce(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
			      struct ethtool_coalesce *ec)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
	if (adapter->hw.mac_type < e1000_82545)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
		return -EOPNOTSUPP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
	if (adapter->itr_setting <= 3)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		ec->rx_coalesce_usecs = adapter->itr_setting;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
static int e1000_set_coalesce(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
			      struct ethtool_coalesce *ec)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
	if (hw->mac_type < e1000_82545)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
		return -EOPNOTSUPP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
	if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
	    ((ec->rx_coalesce_usecs > 3) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	     (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
	    (ec->rx_coalesce_usecs == 2))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
		return -EINVAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	if (ec->rx_coalesce_usecs <= 3) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
		adapter->itr = 20000;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		adapter->itr_setting = ec->rx_coalesce_usecs;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
		adapter->itr = (1000000 / ec->rx_coalesce_usecs);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
		adapter->itr_setting = adapter->itr & ~3;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	if (adapter->itr_setting != 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
		ew32(ITR, 1000000000 / (adapter->itr * 256));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		ew32(ITR, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
static int e1000_nway_reset(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	if (netif_running(netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
		e1000_reinit_locked(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
static void e1000_get_ethtool_stats(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
				    struct ethtool_stats *stats, u64 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
	int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	e1000_update_stats(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
	for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
		char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
		data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
/*	BUG_ON(i != E1000_STATS_LEN); */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
static void e1000_get_strings(struct net_device *netdev, u32 stringset,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
			      u8 *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
	u8 *p = data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
	int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
	switch (stringset) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	case ETH_SS_TEST:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
		memcpy(data, *e1000_gstrings_test,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
			sizeof(e1000_gstrings_test));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
	case ETH_SS_STATS:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
		for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
			memcpy(p, e1000_gstrings_stats[i].stat_string,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
			       ETH_GSTRING_LEN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
			p += ETH_GSTRING_LEN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
/*		BUG_ON(p - data != E1000_STATS_LEN * ETH_GSTRING_LEN); */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
static const struct ethtool_ops e1000_ethtool_ops = {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
	.get_settings           = e1000_get_settings,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	.set_settings           = e1000_set_settings,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	.get_drvinfo            = e1000_get_drvinfo,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	.get_regs_len           = e1000_get_regs_len,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
	.get_regs               = e1000_get_regs,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	.get_wol                = e1000_get_wol,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
	.set_wol                = e1000_set_wol,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	.get_msglevel           = e1000_get_msglevel,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	.set_msglevel           = e1000_set_msglevel,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	.nway_reset             = e1000_nway_reset,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	.get_link               = ethtool_op_get_link,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
	.get_eeprom_len         = e1000_get_eeprom_len,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	.get_eeprom             = e1000_get_eeprom,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
	.set_eeprom             = e1000_set_eeprom,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	.get_ringparam          = e1000_get_ringparam,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	.set_ringparam          = e1000_set_ringparam,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
	.get_pauseparam         = e1000_get_pauseparam,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
	.set_pauseparam         = e1000_set_pauseparam,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	.get_rx_csum            = e1000_get_rx_csum,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	.set_rx_csum            = e1000_set_rx_csum,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
	.get_tx_csum            = e1000_get_tx_csum,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
	.set_tx_csum            = e1000_set_tx_csum,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
	.set_sg                 = ethtool_op_set_sg,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	.set_tso                = e1000_set_tso,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
	.self_test              = e1000_diag_test,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	.get_strings            = e1000_get_strings,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
	.phys_id                = e1000_phys_id,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
	.get_ethtool_stats      = e1000_get_ethtool_stats,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
	.get_sset_count         = e1000_get_sset_count,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	.get_coalesce           = e1000_get_coalesce,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	.set_coalesce           = e1000_set_coalesce,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
void e1000_set_ethtool_ops(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
}