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