devices/e1000/e1000_ethtool-2.6.32-ethercat.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2199 15babd8d4205
permissions -rw-r--r--
devices/ccat: revert "limit rx processing to one frame per poll"

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